Source code for model_package.DNS_Abaqus.convert_tess_2d

#! /usr/bin/env python

import sys
import argparse
import pathlib
import re

sys.path.append('/apps/Cubit-16.12/bin')

import numpy
import cubit
import pandas


[docs] def parse_contents(input_file): """Parse content of Neper output :params str input_file: Input tesselation (.tess) file :returns: DataFrame containing rows of vertex coordinates, DataFrame containing rows of edge-to-vertex connectivity, and dictionary containing ids of faces with lists of face-to-edge connectivity """ vertex_index = [] edge_index = [] face_index = [] with open(input_file, 'r') as f: input_contents = numpy.asarray(f.read().splitlines()) for index, text in enumerate(input_contents): if '**vertex' in text: vertex_index.append(index) if '**edge' in text: edge_index.append(index) if '**face' in text: face_index.append(index) faces = {} # collect vertices vertex_start = vertex_index[0]+2 num_vertices = int(input_contents[vertex_index[0]+1]) vertices = pandas.read_csv(input_file, skiprows=vertex_start, nrows=num_vertices,names=['index','x','y','z','blank'],delimiter=r"\s+", index_col=0) # collect edges edge_start = edge_index[0]+2 num_edges = int(input_contents[edge_index[0]+1]) edges = pandas.read_csv(input_file, skiprows=edge_start, nrows=num_edges,names=['index','a','b','blank'],delimiter=r"\s+", index_col=0) # collect faces face_start = face_index[0]+2 num_faces = int(input_contents[face_index[0]+1]) desired_lines = list(input_contents[face_start:face_start+num_faces*4]) line_to_grab = 1 for face_id in range(0,num_faces): line = desired_lines[face_id*4 + line_to_grab] items = re.split(r'\s+', line) faces[face_id+1] = [str(abs(int(i))) for i in items[2:]] return vertices, edges, faces
[docs] def create_geometry(vertices, edges, faces, stl_file): """Create geometry from Neper output :params DataFrame vertices: Pandas DataFrame containing rows of vertex coordinates :params DataFrame edges: Pandas DataFrame containing rows of edge-to-vertex connectivity :params dict faces: Dictionary containing ids of faces with lists of face-to-edge connectivity :params str stl_file: Optional filename to save STL geometry without extension :returns: Write ``{stl_file}.cub`` """ cubit.init(['cubit', '-noecho', '-nojournal', '-nographics', '-batch']) cubit.cmd('new') cubit.cmd('reset') # create all the points for index, row in vertices.iterrows(): cubit.cmd(f'create vertex {row["x"]} {row["y"]} {row["z"]}') # create all the edges for index, row in edges.iterrows(): cubit.cmd(f'create curve vertex {row["a"]} {row["b"]}') # create all the faces for face in faces.keys(): cubit.cmd(f'create surface curve {" ".join(faces[face])}') # define cubit.cmd(f'save as "{stl_file}.cub" overwrite') #cubit.cmd(f'export stl "{stl_file}.stl" volume {" ".join(str(cell+num_faces) for cell in polyhedra.keys())} fast overwrite') return 0
[docs] def create_mesh(stl_file, mesh_file, faces, sidesets, seed_size): """Create mesh from Neper output :params str stl_file: Optional filename to save STL geometry without extension :params str mesh_file: Optional filename to create an Abaqus mesh without extension :params dict sidesets: Dictionary containing names of surfaces and geometric search strings :params float seed_size: The approximate mesh size :returns: Write ``{mesh_file}.cub`` and ``{mesh_file}.inp`` """ cubit.init(['cubit', '-noecho', '-nojournal', '-nographics', '-batch']) cubit.cmd('new') cubit.cmd('reset') cubit.cmd(f'open "{stl_file}.cub"') #cubit.cmd('set developer commands on') cubit.cmd('imprint all') cubit.cmd('surface all scheme trimesh') if seed_size < 1.0: cubit.cmd(f'surface all size {seed_size}') cubit.cmd('mesh surface all') for cell in faces.keys(): cubit.cmd(f'block {cell} surface {cell}') cubit.cmd('block all element type TRI3') # new using min-max sideset_num = 1 for sideset in sidesets.keys(): cubit.cmd(f'nodeset {sideset_num} add curve with {sidesets[sideset]}') cubit.cmd(f'nodeset {sideset_num} name "{sideset}"') cubit.cmd(f'sideset {sideset_num} add curve with {sidesets[sideset]}') cubit.cmd(f'sideset {sideset_num} name "{sideset}"') sideset_num = sideset_num + 1 # Corner cubit.cmd(f'nodeset {sideset_num} add vertex with x_max < 0.01 with y_max < 0.01') cubit.cmd(f'nodeset {sideset_num} name "corner"') # Output cubit.cmd(f'save as "{mesh_file}.cub" overwrite') blocks = [str(cell) for cell in faces.keys()] cubit.cmd(f'export abaqus "{mesh_file}.inp" block {" ".join(blocks)} overwrite partial dimension 2') #cubit.cmd(f'export abaqus "{mesh_file}.inp" overwrite partial dimension 2') return 0
[docs] def convert_tess(input_file, stl_file=None, mesh_file=None, seed_size=1.0): """Convert a 2D tesselation file output by Neper to STL and create an Abaqus mesh :params str input_file: Input tesselation (.tess) file :params str stl_file: Optional filename to save STL geometry without extension :params str mesh_file: Optional filename to create an Abaqus mesh without extension :params float seed_size: The approximate mesh size """ vertices, edges, faces = parse_contents(input_file) print(vertices) print(edges) print('face') print(faces) sidesets = {'side1': 'x_min > 0.99', 'side2': 'y_min > 0.99', 'side3': 'x_max < 0.01', 'side4': 'y_max < 0.01',} if stl_file: create_geometry(vertices, edges, faces, stl_file) if mesh_file: create_mesh(stl_file, mesh_file, faces, sidesets, seed_size) return 0
def get_parser(): script_name = pathlib.Path(__file__) prog = f"python {script_name.name} " cli_description = "Convert a 2D tesselation file output by Neper to STL and create an Abaqus mesh" parser = argparse.ArgumentParser(description=cli_description, prog=prog) parser.add_argument("--input-file", type=str, required=True, help="Input tesselation (.tess) file") parser.add_argument("--stl-file", type=str, required=False, default=None, help="Optional filename to save STL of geometry without extension") parser.add_argument("--mesh-file", type=str, required=False, default=None, help="Optional filename to create an Abaqus mesh without extension") parser.add_argument('--seed-size', type=float, required=False, default=1.0, help='The approximate mesh size') return parser if __name__ == "__main__": parser = get_parser() args, unknown = parser.parse_known_args() sys.exit(convert_tess(input_file=args.input_file, stl_file=args.stl_file, mesh_file=args.mesh_file, seed_size=args.seed_size, ))