def apply_pml(pml_elems, face_constraints, edge_constraints, nodefile="nodes.dyn", elefile="elems.dyn", pmlfile="elems_pml.dyn", bcfile="bc.dyn", pml_partID=2): """driver function to apply PML boundary conditions Args: pml_elems (str): 3x2 array of ints specifying thickness of PML elements (5--10) on each PML layer face_constraints: 3x2 array of strings, specifying the BCs on each face (3), min/max (2) edge_constraints (str): 1x6 vector of BCs on each edge nodefile (str): default - input file for the node definitions elefile (str): default - input file for the element definitions pmlfile (str): output file for the elements w/ PMLs bcfile (str): output file for the boundary conditions pml_partID (int): PID for the PML elements """ import fem_mesh nodeIDcoords = fem_mesh.load_nodeIDs_coords(nodefile) [snic, axes] = fem_mesh.SortNodeIDs(nodeIDcoords) elems = fem_mesh.load_elems(elefile) sorted_elems = fem_mesh.SortElems(elems, axes) sorted_pml_elems = assign_pml_elems(sorted_elems, pml_elems, pml_partID) write_pml_elems(sorted_pml_elems, pmlfile) bcdict = assign_node_constraints(snic, axes, face_constraints) bcdict = constrain_sym_pml_nodes(bcdict, snic, axes, pml_elems, edge_constraints) bcdict = assign_edge_sym_constraints(bcdict, snic, axes, edge_constraints) write_bc(bcdict, bcfile)
def extract_top_plane_nodes(nodefile, top_face): """ Args: nodefile: param top_face: top_face: Returns: planeNodeIDs """ import numpy as np import fem_mesh top_face = np.array(top_face) nodeIDcoords = fem_mesh.load_nodeIDs_coords(nodefile) [snic, axes] = fem_mesh.SortNodeIDs(nodeIDcoords) # extract spatially-sorted node IDs on a the top z plane axis = int(np.floor(np.divide(top_face.nonzero(), 2))) if np.mod(top_face.nonzero(), 2) == 1: plane = (axis, axes[axis].max()) else: plane = (axis, axes[axis].min()) planeNodeIDs = fem_mesh.extractPlane(snic, axes, plane) return planeNodeIDs
def run(dynadeck, disp_comp=2, disp_scale=-1e4, ressim="res_sim.mat", nodedyn="nodes.dyn", dispout="disp.dat", legacynodes=False, plane_pos: float = 0.0, plane_orientation: int = 0, specific_times: Optional[list] = None): """helper function to run high-level, 2D plane extraction look at using extract3Darfidata to get full, 3D datasets exported (e.g., to view in Paraview) Args: dynadeck (str): main dyna input deck disp_comp (int): component of displacement to extract disp_scale (float): displacement scaling ressim (str): result filename to write nodedyn (str): node defintion input filename dispout (str): binary displacement input filename legacynodes (Boolean): node IDs written with each timestep in dispout plane_pos (float): position of the plane to extract (in the specified plane_orientation) plane_orientation (int): orientation plane to extract from (0 = elev, 1 = lateral, 2 = axial) specific_times (list): optional list of specific time indices to extract """ import sys from pathlib import Path meshPath = Path(__file__).parents[1] / "mesh" sys.path.insert(0, str(meshPath)) import fem_mesh try: plane_pos except NameError: plane_pos = ele_pos node_id_coords = fem_mesh.load_nodeIDs_coords(nodedyn) [snic, axes] = fem_mesh.SortNodeIDs(node_id_coords) image_plane = extract_image_plane(snic, axes, plane_pos, plane_orientation) header = read_header(dispout) if specific_times is None: t = __gen_t(extract_dt(dynadeck), header['num_timesteps']) else: t = __gen_t(extract_dt(dynadeck), specific_times) arfidata = extract_arfi_data(dispout, header, image_plane, disp_comp, disp_scale, legacynodes, specific_times) axis_scale = (-10, 10, -10) save_res_sim(ressim, arfidata, axes, t, axis_scale, plane_pos, plane_orientation) return 0
def test_loadnodeidscoords(): from fem_mesh import load_nodeIDs_coords nodefile = '%s/nodes.dyn' % myPath nodeIDcoords = load_nodeIDs_coords(nodefile) assert nodeIDcoords[0][1] == -1.0 assert nodeIDcoords[-1][0] == 1331 assert nodeIDcoords[-1][2] == 1.0
def nodeIDcoords(): """create node ID and coordinate matrix from nodes.dyn :returns: [snic, axes] """ from fem_mesh import load_nodeIDs_coords nodefile = '%s/nodes.dyn' % myPath nodeIDcoords = load_nodeIDs_coords(nodefile) return nodeIDcoords
def extract3Darfidata(dynadeck="dynadeck.dyn", disp_comp=2, disp_scale=-1e4, ressim="res_sim.h5", nodedyn="nodes.dyn", dispout="disp.dat", specific_times=None): """Extract 3D volume of specified displacement component. Args: dynadeck (str): LS-DYNA3D input deck (used to get dt) disp_comp (int): displacement component to extract (0, 1, 2) disp_scale (float): displacement scaling factor (cm -> um) ressim (str): output file name [.mat, .h5, .pvd] nodedyn (str): node input file dispout (str): binary displacement data specific_times (list): optional list of specific time indices """ import sys from pathlib import Path meshPath = Path(__file__).parents[1] / "mesh" sys.path.insert(0, str(meshPath)) import fem_mesh if not ressim.endswith(('.mat', '.h5', '.pvd')): raise NameError('Output res_sim filename not supported') node_id_coords = fem_mesh.load_nodeIDs_coords(nodedyn) [snic, axes] = fem_mesh.SortNodeIDs(node_id_coords) header = read_header(dispout) if specific_times is None: t = __gen_t(extract_dt(dynadeck), header['num_timesteps']) else: t = __gen_t(extract_dt(dynadeck), specific_times) arfidata = extract_arfi_data(dispout, header, snic['id'], disp_comp, disp_scale, legacynodes=False, specific_times=specific_times) save_res_sim(ressim, arfidata, axes, t)
def apply_nonreflect(face_constraints, edge_constraints, nodefile="nodes.dyn", elefile="elems.dyn", bcfile="bc.dyn", segfile="nonreflect_segs.dyn"): """driver function to generate non-reflecting boundaries Args: face_constraints (str): vector of face constraints, ordered xmin to zmax edge_constraints (str): vector of edge constraints, ordered xmin to zmax nodefile (str): default - 'nodes.dyn' elefile (str): default - 'elems.dyn' bcfile (str): default - 'bc.dyn' segfile (str): default - 'nonreflect_segs.dyn' Returns: 0 on success """ import fem_mesh nodeIDcoords = fem_mesh.load_nodeIDs_coords(nodefile) [snic, axes] = fem_mesh.SortNodeIDs(nodeIDcoords) segID = 1 seg_names = [['XMIN', 'XMAX'], ['YMIN', 'YMAX'], ['ZMIN', 'ZMAX']] SEGBCFILE = open(segfile, 'w') for a in range(0, 3): for m in range(0, 2): if face_constraints[a][m] == '1,1,1,1,1,1': if m == 0: axis_limit = axes[a][0] else: axis_limit = axes[a][-1] planeNodeIDs = fem_mesh.extractPlane(snic, axes, (a, axis_limit)) segID = writeSeg(SEGBCFILE, seg_names[a][m], segID, planeNodeIDs) write_nonreflecting(SEGBCFILE, segID) SEGBCFILE.close() bcdict = assign_node_constraints(snic, axes, face_constraints) bcdict = assign_edge_sym_constraints(bcdict, snic, axes, edge_constraints) write_bc(bcdict, bcfile) return 0
def run(dynadeck, disp_comp=2, disp_scale=-1e4, ressim="res_sim.mat", nodedyn="nodes.dyn", dispout="disp.dat", legacynodes=False): """helper function to run high-level, 2D plane extraction look at using extract3Darfidata to get full, 3D datasets exported (e.g., to view in Paraview) Args: dynadeck (str): main dyna input deck disp_comp (int): component of displacement to extract disp_scale (float): displacement scaling ressim (str): result filename to write nodedyn (str): node defintion input filename dispout (str): binary displacement input filename legacynodes (Boolean): node IDs written with each timestep in dispout """ import sys from pathlib import Path meshPath = Path(__file__).parents[1] / "mesh" sys.path.insert(0, str(meshPath)) import fem_mesh node_id_coords = fem_mesh.load_nodeIDs_coords(nodedyn) [snic, axes] = fem_mesh.SortNodeIDs(node_id_coords) image_plane = extract_image_plane(snic, axes, ele_pos=0.0) header = read_header(dispout) t = __gen_t(extract_dt(dynadeck), header['num_timesteps']) arfidata = extract_arfi_data(dispout, header, image_plane, disp_comp, disp_scale, legacynodes) save_res_sim(ressim, arfidata, axes, t) return 0
def extract3Darfidata(dynadeck=None, disp_comp=2, disp_scale=-1e4, ressim="res_sim.h5", nodedyn="nodes.dyn", dispout="disp.dat"): """Extract 3D volume of specified displacement component. Args: dynadeck (str): LS-DYNA3D input deck (used to get dt) disp_comp (int): displacement component to extract (0, 1, 2) disp_scale (float): displacement scaling factor (cm -> um) ressim (str): output file name [.mat, .h5, .pvd] nodedyn (str): node input file dispout (str): binary displacement data """ import os import sys myPath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, myPath + '/../mesh/') import fem_mesh import numpy as np if not ressim.endswith(('.mat', '.h5', '.pvd')): raise NameError('Output res_sim filename not supported') node_id_coords = fem_mesh.load_nodeIDs_coords(nodedyn) [snic, axes] = fem_mesh.SortNodeIDs(node_id_coords) header = read_header(dispout) dt = extract_dt(dynadeck) t = [float(x) * dt for x in range(0, header['num_timesteps'])] arfidata = extract_arfi_data(dispout, header, snic['id'], disp_comp, disp_scale, legacynodes=False) save_res_sim(ressim, arfidata, axes, t)
def run(dynadeck, disp_comp=2, disp_scale=-1e4, ressim="res_sim.mat", nodedyn="nodes.dyn", dispout="disp.dat", legacynodes=False): """ Args: dynadeck (str): main dyna input deck disp_comp (int): component of displacement to extract disp_scale (float): displacement scaling ressim (str): result filename to write nodedyn (str): node defintion input filename dispout (str): binary displacement input filename legacynodes (Boolean): node IDs written with each timestep in dispout """ import os import sys myPath = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, myPath + '/../mesh/') import fem_mesh node_id_coords = fem_mesh.load_nodeIDs_coords(nodedyn) [snic, axes] = fem_mesh.SortNodeIDs(node_id_coords) image_plane = extract_image_plane(snic, axes, ele_pos=0.0) header = read_header(dispout) t = gen_t(extract_dt(dynadeck), header['num_timesteps']) arfidata = extract_arfi_data(dispout, header, image_plane, disp_comp, disp_scale, legacynodes) save_res_sim(ressim, arfidata, axes, t) return 0
def apply_face_bc_only(face_constraints, nodefile="nodes.dyn", bcfile="bc.dyn"): """Driver function to apply node BCs just to faces. Args: face_constraints (tuple): 3x2 tuple of strings (('0,0,0,0,0,0'), ('0,0,0,0,0,0'), ('0,0,0,0,0,0'), ('0,0,0,0,0,0'), ('0,0,0,0,0,0'), ('0,0,0,0,0,0')) Specify face BCs as ((xmin, xmax), (ymin, ymax), (zmin, zmax)) nodefile (str): input file for node definitions (*NODE) bcfile (str): output file for boundary conditions (*BOUNDARY_SPC_NODE) """ import fem_mesh nodeIDcoords = fem_mesh.load_nodeIDs_coords(nodefile) [snic, axes] = fem_mesh.SortNodeIDs(nodeIDcoords) bcdict = assign_node_constraints(snic, axes, face_constraints) write_bc(bcdict, bcfile)