Source code for model_package.Tardigrade_MOOSE.cylinder_from_bounds

import sys
import os
import argparse
import pathlib

import cubit
import pandas
import numpy
import subprocess


[docs] def mesh(rad, height, x0, y0, z0, seed_size, output_file, cut=False): ''' Mesh a cylinder using Cubit :param float rad: Cylinder radius :param float height: Cylinder height :param float x0: The x-distance to translate the cylinder :param float y0: The y-distance to translate the cylinder :param float z0: The z-distance to translate the cylinder :param float seed-size: The approximate mesh size :param str output_file: The output filename :param bool cut: The option to cut geometry into octants, pass string "True" if desired :returns: ``{output_file}.e`` ''' cubit.init(['cubit', '-noecho', '-nojournal', '-nographics', '-batch']) cubit.cmd('new') cubit.cmd('reset') cubit.cmd(f'create Cylinder height {height} radius {rad}') if cut: # Cut with planes cubit.cmd('webcut volume all with plane xplane offset 0') cubit.cmd('webcut volume all with plane yplane offset 0') cubit.cmd('webcut volume all with plane zplane offset 0') # Side sets cubit.cmd('sideset 1 add surface 28 20 26 14') cubit.cmd('sideset 1 name "top"') cubit.cmd('sideset 2 add surface 24 16 30 18') cubit.cmd('sideset 2 name "bottom"') cubit.cmd('sideset 3 add surface 41 59 47 61') cubit.cmd('sideset 3 name "x_plane"') cubit.cmd('sideset 4 add surface 58 50 62 54') cubit.cmd('sideset 4 name "y_plane"') # Mesh and move cubit.cmd('imprint volume all') cubit.cmd('merge volume all') cubit.cmd(f'volume all size {seed_size}') cubit.cmd('mesh volume all') cubit.cmd(f'move Volume all x {x0} y {y0} z {z0} include_merged') # Make a new block for all elements to export cubit.cmd('block 9 add hex all') cubit.cmd('block 9 name "all"') # Export cubit.cmd(f'export mesh "{output_file}.e" block 9 overwrite') else: # Side sets cubit.cmd('sideset 1 add surface 3') cubit.cmd('sideset 1 name "top"') cubit.cmd('sideset 2 add surface 2') cubit.cmd('sideset 2 name "bottom"') # Mesh and move cubit.cmd(f'volume all size {seed_size}') cubit.cmd('mesh volume all') cubit.cmd(f'move Volume all x {x0} y {y0} z {z0} include_merged') # Export cubit.cmd(f'export mesh "{output_file}.e" overwrite') return 0
[docs] def cylinder_from_bounds(output_file, bounds_file, seed_size, cut=False, xdmf=True, ascii=False): '''Create a cylinder mesh from the bounds of a DNS file :param str output_file: The output filename :param str bounds_file: The file containing the bounds of the DNS :param float seed_size: The approximate mesh size :param bool cut: The option to cut geometry into octants, pass string "True" if desired :param bool xdmf: The option to convert default exodus mesh to XDMF (binary) :param bool ascii: The option to convert binary XDMF mesh to ascii Calls "mesh" function and converts ``{output_file}.e`` to ``{output_file}.xdmf`` ''' # Process the bounds data to calculate cylinder geometry info bounds_data = pandas.read_csv(bounds_file, sep=',') xmin = bounds_data['xmin'][0] xmax = bounds_data['xmax'][0] ymin = bounds_data['ymin'][0] ymax = bounds_data['ymax'][0] zmin = bounds_data['zmin'][0] zmax = bounds_data['zmax'][0] radx = (xmax - xmin) / 2 rady = (ymax - ymin) / 2 rad = numpy.mean([radx, rady]) height = zmax - zmin x0 = xmin + rad y0 = ymin + rad z0 = zmin + (height / 2) # create mesh mesh(rad, height, x0, y0, z0, seed_size, output_file, cut) # convert to XDMF with subprocess if xdmf: subprocess.run([f'meshio convert {output_file}.e {output_file}.xdmf'], shell=True) if ascii: subprocess.run([f'meshio ascii {output_file}.xdmf'], shell=True) return 0
def get_parser(): script_name = pathlib.Path(__file__) prog = f"python {script_name.name} " cli_description = "Create a cylinder mesh from the bounds of a DNS file." parser = argparse.ArgumentParser(description=cli_description, prog=prog) parser.add_argument('--output-file', type=str, required=True, help="The output filename") parser.add_argument('--bounds-file', type=str, required=True, help='The file containing the bounds of the DNS') parser.add_argument('--seed-size', type=float, required=True, help='The approximate mesh size') parser.add_argument('--cut', type=str, required=False, help='The option to cut geometry into octants, pass string "True" if desired') parser.add_argument('--xdmf', type=str, required=False, help='The option to convert default exodus mesh to XDMF (binary)') parser.add_argument('--ascii', type=str, required=False, help='The option to convert binary XDMF mesh to ascii') return parser if __name__ == '__main__': parser = get_parser() args = parser.parse_args() sys.exit(cylinder_from_bounds(output_file=args.output_file, bounds_file=args.bounds_file, seed_size=args.seed_size, cut=args.cut, xdmf=bool(args.xdmf), ascii=bool(args.ascii), ))