Source code for model_package.Tardigrade_MOOSE.brazilian_disk_apparatus

import sys
import os
import argparse
import pathlib

import cubit
import pandas
import numpy
import subprocess

from misc_utilities import str2bool


[docs] def brazilian_disk_apparatus(output_file, specimen_seed_size, platen_seed_size, height, width, chord, app_rad, app_dep, spec_rad, spec_dep, tol, x0=0., y0=0., z0=0., export_platens=True): '''Create a Brazilian Disk specimen and loading apparatus :param str output_file: The output filename :param float specimen_seed_size: The approximate mesh size for the specimen :param float platen_seed_size: The approximate mesh size for the platen :param float height: The height of a single Brazilian disk compression platen :param float width: The base width of a Brazilian disk compression platen :param float chord: The chord distance of the Brazilian disk compression platen :param float app_rad: The radius of curvature of the Brazilian disk compression platen :param float depth: The extrusion depth of the Brazilian disk compression platen :param float spec_rad: The radius of the Brazilian disk compression specimen :param float spec_dep: The extrusion depth of the Brazilian disk compression specimen :param float tol: A tolerance / gap distance to insert between Brazilian disk compression specimen and platens :param float x0: The x-location to move geometry for the center of the Brazil Disk :param float y0: The y-location to move geometry for the center of the Brazil Disk :param float z0: The z-location to move geometry for the center of the Brazil Dis :param bool export_platens: Flag to export platen meshes of the brazilian disk apparatus :returns: Write ``{output_file}.cub``, ``{output_file}_specimen.inp``, and optionally ``{output_file}_bottom_platen.inp`` and ``{output_file}_top_platen.inp`` ''' perp_dist = app_rad - numpy.sqrt((app_rad**2 - (0.5*chord)**2)) print(perp_dist) bottom_spec = height - perp_dist gap = 2*(spec_rad - perp_dist) offset = (app_dep - spec_dep)/2 width_2 = (width - chord)/2. # Platen 1 cubit.cmd('create vertex 0 0 0') cubit.cmd(f'create vertex 0 {height} 0') cubit.cmd(f'create vertex {width} 0 0') cubit.cmd(f'create vertex {width} {height} 0') cubit.cmd(f'create vertex {width_2} {height} 0') cubit.cmd(f'create vertex {width - width_2} {height} 0') cubit.cmd('create curve vertex 1 2') cubit.cmd('create curve vertex 1 3') cubit.cmd('create curve vertex 3 4') cubit.cmd('create curve vertex 2 5') cubit.cmd('create curve vertex 6 4') cubit.cmd(f'create curve arc vertex 5 6 radius {app_rad} normal 0 0 1') cubit.cmd('create surface curve all') cubit.cmd(f'sweep surface 1 vector 0 0 1 distance {app_dep}') # Platen 2 cubit.cmd('Volume 1 copy rotate 180 about x') cubit.cmd(f'move Volume 2 x 0 y {2*height + gap + 2*tol} z {app_dep} include_merged') # Specimen cubit.cmd(f'create curve arc radius {spec_rad} center location {width/2} {bottom_spec+spec_rad+tol} \ {offset} normal 0 0 1 start angle 0 stop angle 360') cubit.cmd('create surface curve 37') cubit.cmd(f'sweep surface 17 vector 0 0 1 distance {spec_dep}') # Partition cubit.cmd('webcut volume all with general plane curve 18') cubit.cmd('webcut volume 3 6 with general plane curve 75') # Move move_x = width/2 move_y = bottom_spec+spec_rad+tol move_z = offset + spec_dep/2 cubit.cmd(f'move Volume all x {x0 - move_x} y {y0 - move_y} z {z0 - move_z} include_merged') # Blocks and sets cubit.cmd('block 1 add volume 1 4') cubit.cmd('block 1 name "bottom_platen"') cubit.cmd('block 2 add volume 2 5') cubit.cmd('block 2 name "top_platen"') cubit.cmd('block 3 add volume 3 6 7 8') cubit.cmd('block 3 name "specimen"') ## sidesets cubit.cmd('sideset 1 add surface 23 27') cubit.cmd('sideset 1 name "bottom_platen_bottom"') cubit.cmd('sideset 2 add surface 33 37') cubit.cmd('sideset 2 name "top_platen_top"') cubit.cmd('sideset 3 add surface 53 55 60 66') cubit.cmd('sideset 3 name "back"') cubit.cmd('sideset 4 add surface 31 38') cubit.cmd('sideset 4 name "top_platen_contact"') cubit.cmd('sideset 5 add surface 21 28') cubit.cmd('sideset 5 name "bottom_platen_contact"') cubit.cmd('sideset 6 add surface 47 50') cubit.cmd('sideset 6 name "specimen_top"') cubit.cmd('sideset 7 add surface 46 57') cubit.cmd('sideset 7 name "specimen_bottom"') cubit.cmd('sideset 8 add surface 2') cubit.cmd('sideset 8 name "bottom_platen_side"') cubit.cmd('sideset 9 add surface 9') cubit.cmd('sideset 9 name "top_platen_side"') cubit.cmd('sideset 10 add surface 22 29') cubit.cmd('sideset 10 name "bottom_platen_back"') cubit.cmd('sideset 11 add surface 34 36') cubit.cmd('sideset 11 name "top_platen_back"') cubit.cmd('sideset 12 add surface 51 58 62 64') cubit.cmd('sideset 12 name "specimen_front"') cubit.cmd('sideset 13 add surface 53 55 60 66') cubit.cmd('sideset 13 name "specimen_back"') ## nodesets cubit.cmd('nodeset 1 add surface 23 27') cubit.cmd('nodeset 1 name "bottom_platen_bottom"') cubit.cmd('nodeset 2 add surface 33 37') cubit.cmd('nodeset 2 name "top_platen_top"') cubit.cmd('nodeset 3 add surface 53 55 60 66') cubit.cmd('nodeset 3 name "back"') cubit.cmd('nodeset 4 add surface 31 38') cubit.cmd('nodeset 4 name "top_platen_contact"') cubit.cmd('nodeset 5 add surface 21 28') cubit.cmd('nodeset 5 name "bottom_platen_contact"') cubit.cmd('nodeset 6 add surface 47 50') cubit.cmd('nodeset 6 name "specimen_top"') cubit.cmd('nodeset 7 add surface 46 57') cubit.cmd('nodeset 7 name "specimen_bottom"') cubit.cmd('nodeset 8 add surface 2') cubit.cmd('nodeset 8 name "bottom_platen_side"') cubit.cmd('nodeset 9 add surface 9') cubit.cmd('nodeset 9 name "top_platen_side"') cubit.cmd('nodeset 10 add surface 22 29') cubit.cmd('nodeset 10 name "bottom_platen_back"') cubit.cmd('nodeset 11 add surface 34 36') cubit.cmd('nodeset 11 name "top_platen_back"') cubit.cmd('nodeset 12 add surface 51 58 62 64') cubit.cmd('nodeset 12 name "specimen_front"') cubit.cmd('nodeset 13 add surface 53 55 60 66') cubit.cmd('nodeset 13 name "specimen_back"') cubit.cmd('nodeset 15 add curve 74') cubit.cmd('nodeset 15 name "top_line_load"') cubit.cmd('nodeset 16 add curve 72') cubit.cmd('nodeset 16 name "bottom_line_load"') # Mesh cubit.cmd('merge volume 3 6 7 8') cubit.cmd('merge volume 1 4') cubit.cmd('merge volume 2 5') cubit.cmd(f'volume 3 6 7 8 size {specimen_seed_size}') cubit.cmd('mesh volume 3 6 7 8') cubit.cmd(f'volume 1 4 size {platen_seed_size}') cubit.cmd('mesh volume 1 4') cubit.cmd(f'volume 2 5 size {platen_seed_size}') cubit.cmd('mesh volume 2 5') # All nodes cubit.cmd('nodeset 14 add node all') cubit.cmd('nodeset 14 name "all"') # Export if export_platens == True: cubit.cmd(f'export abaqus "{output_file}_bottom_platen.inp" block 1 source_csys 0 target_csys 0 partial dimension 3 overwrite') cubit.cmd(f'export abaqus "{output_file}_top_platen.inp" block 2 source_csys 0 target_csys 0 partial dimension 3 overwrite') else: cubit.cmd('delete block 1 2') cubit.cmd('delete volume 1 2 4 5') cubit.cmd('delete nodeset 1 2 4 5 8 9 10 11') cubit.cmd('delete sideset 1 2 4 5 8 9 10 11') cubit.cmd(f'save as "{output_file}.cub" overwrite') cubit.cmd(f'export mesh "{output_file}.e" overwrite') cubit.cmd(f'export abaqus "{output_file}_specimen.inp" block 3 source_csys 0 target_csys 0 partial dimension 3 overwrite') return
def get_parser(): script_name = pathlib.Path(__file__) prog = f"python {script_name.name} " cli_description = "Create a Brazilian Disk specimen and loading apparatus" parser = argparse.ArgumentParser(description=cli_description, prog=prog) parser.add_argument('--output-file', type=str, required=True, help="The output filename") parser.add_argument('--specimen-seed-size', type=float, required=True, help='The approximate mesh size for the specimen') parser.add_argument('--platen-seed-size', type=float, required=True, help='The approximate mesh size for the platens') parser.add_argument('--height', type=float, required=True, help='The height of a single Brazilian disk compression platen') parser.add_argument('--width', type=float, required=True, help='The base width of a Brazilian disk compression platen') parser.add_argument('--chord', type=float, required=True, help='The chord distance of the Brazilian disk compression platen') parser.add_argument('--app-rad', type=float, required=True, help='The radius of curvature of the Brazilian disk compression platen') parser.add_argument('--app-dep', type=float, required=True, help='The extrusion depth of the Brazilian disk compression platen') parser.add_argument('--spec-rad', type=float, required=True, help='The radius of the Brazilian disk compression specimen') parser.add_argument('--spec-dep', type=float, required=True, help='The extrusion depth of the Brazilian disk compression specimen') parser.add_argument('--tol', type=float, required=False, default=0.001, help='A tolerance / gap distance to insert between Brazilian disk \ compression specimen and platens') parser.add_argument('--x0', type=float, required=False, default=0., help='The x-location to move geometry for the center of the Brazil Disk') parser.add_argument('--y0', type=float, required=False, default=0., help='The y-location to move geometry for the center of the Brazil Disk') parser.add_argument('--z0', type=float, required=False, default=0., help='The z-location to move geometry for the center of the Brazil Disk') parser.add_argument('--export-platens', type=str, required=False, default='True', help='Flag to export platen meshes of the brazilian disk apparatus') return parser if __name__ == '__main__': parser = get_parser() args = parser.parse_args() sys.exit(brazilian_disk_apparatus(output_file=args.output_file, specimen_seed_size=args.specimen_seed_size, platen_seed_size=args.platen_seed_size, height=args.height, width=args.width, chord=args.chord, app_rad=args.app_rad, app_dep=args.app_dep, spec_rad=args.spec_rad, spec_dep=args.spec_dep, tol=args.tol, x0=args.x0, y0=args.y0, z0=args.z0, export_platens=str2bool(args.export_platens), ))