How do I convert LS-Dyna results to USD format?
Ayush Kumar
Member, Moderator, Employee Posts: 444
✭✭✭✭
Comments
-
This example converts a Shell Model to USD format and stores some results at several time-steps as Attributes for the Primitive "/d3plot"
Tested with:
- usd-core version 23.11
- Python version 3.10.10
- ansys-dpf-core 0.10.0
from pxr import Sdf, Usd, UsdGeom from ansys.dpf import core as dpf timescopingToken = "ansys:lsdyna:timescoping" nodeIndicesToken = "ansys:lsdyna:nodeindices" attributesTokens = ["ansys:lsdyna:acceleration", "ansys:lsdyna:displacement", "ansys:lsdyna:stress", "ansys:lsdyna:velocity"] globalFieldTokenK = ["ansys:lsdyna:global_k", "ansys:lsdyna:global_k_time"] globalFieldTokenU = ["ansys:lsdyna:global_u", "ansys:lsdyna:global_u_time"] globalFieldTokenH = ["ansys:lsdyna:global_h", "ansys:lsdyna:global_h_time"] globalFieldTokenV = ["ansys:lsdyna:global_v", "ansys:lsdyna:global_v_time"] descriptionToken = "ansy:dpf:description" fieldTypeToken = "ansys:dpf:selectedFieldType" nbFramesPerTimestep = 5 # create mesh from a d3plot file def create_dpf_prim_with_stage(filepath: str, primname: str, stage): # loads the data print("Loading model " + filepath) ds = dpf.DataSources() ds.set_result_file_path(filepath, "d3plot") # Result file # Instantiate Model Class model = dpf.Model(ds) nbResults = model.metadata.time_freq_support.n_sets timeScoping = [] for ts in range(nbResults): timeScoping.append(ts) # Whole mesh mesh = model.metadata.meshed_region # Extract skin mesh op = dpf.operators.mesh.skin(mesh=mesh) skin_mesh = op.outputs.mesh.get_data() # Extract Coordinates results coord = model.results.coordinates(time_scoping=timeScoping) coord_fc = coord.outputs.fields_container.get_data() # Extract Acceleration results accel = model.results.acceleration(time_scoping=timeScoping) accel_fc = accel.outputs.fields_container.get_data() # Extract Displacement results disp = model.results.displacement(time_scoping=timeScoping) disp_fc = disp.outputs.fields_container.get_data() # Extract Stress results stress = model.results.stress(time_scoping=timeScoping) stress_fc = stress.outputs.fields_container.get_data() # Extract Velocity results vel = model.results.velocity(time_scoping=timeScoping) vel_fc = vel.outputs.fields_container.get_data() # globals K = model.results.global_kinetic_energy.eval() U = model.results.global_internal_energy().eval() H = model.results.global_total_energy().eval() V = model.results.global_velocity().eval() # add info to the current stage usd_mesh = UsdGeom.Mesh.Define(stage, primname) usd_mesh.GetPrim().CreateAttribute(globalFieldTokenK[0], Sdf.ValueTypeNames.FloatArray).Set(K[0].data) usd_mesh.GetPrim().CreateAttribute(globalFieldTokenU[0], Sdf.ValueTypeNames.FloatArray).Set(U[0].data) usd_mesh.GetPrim().CreateAttribute(globalFieldTokenH[0], Sdf.ValueTypeNames.FloatArray).Set(H[0].data) usd_mesh.GetPrim().CreateAttribute(globalFieldTokenV[0], Sdf.ValueTypeNames.FloatArray).Set(V[0].data) usd_mesh.GetPrim().CreateAttribute(globalFieldTokenK[1], Sdf.ValueTypeNames.FloatArray).Set( K.time_freq_support.time_frequencies.data) usd_mesh.GetPrim().CreateAttribute(globalFieldTokenU[1], Sdf.ValueTypeNames.FloatArray).Set( U.time_freq_support.time_frequencies.data) usd_mesh.GetPrim().CreateAttribute(globalFieldTokenH[1], Sdf.ValueTypeNames.FloatArray).Set( H.time_freq_support.time_frequencies.data) usd_mesh.GetPrim().CreateAttribute(globalFieldTokenV[1], Sdf.ValueTypeNames.FloatArray).Set( V.time_freq_support.time_frequencies.data) # add number of timesteps as an attribute usd_mesh.GetPrim().CreateAttribute(timescopingToken, Sdf.ValueTypeNames.IntArray).Set(timeScoping) """indices, faceCount and nodeIndices doesn't change overtime.""" nbElements = len(mesh.elements) indices = [] faceCounts = [] nodeIndices = [] # fills vertices, indices and face counts for elementId in range(nbElements): element = mesh.elements[elementId] # face represents a triangle or quad faceCounts.append(len(element.nodes)) # adds vertex coordinates for node in element.nodes: nodeIndices.append(node.index) # add indices indices.append(len(indices)) # Create Indices usd_mesh.GetFaceVertexIndicesAttr().Set(indices) # Face counts (3 for tris, 4 for quads...) usd_mesh.GetFaceVertexCountsAttr().Set(faceCounts) # Node indoces for further field access usd_mesh.GetPrim().CreateAttribute(nodeIndicesToken, Sdf.ValueTypeNames.IntArray).Set(nodeIndices) # descriptions usd_mesh.GetPrim().CreateAttribute(descriptionToken, Sdf.ValueTypeNames.String).Set( model.metadata.result_info.__str__()) # Go through all the timesteps for i in range(nbResults): print("Importing timecode " + str(i) + "/" + str(nbResults)) # Create the current timecode timeCode = Usd.TimeCode(float(i * nbFramesPerTimestep)) # set custom attributes in the USD usd_mesh.GetPrim().CreateAttribute(attributesTokens[0], Sdf.ValueTypeNames.Float3Array).Set(accel_fc[i].data, timeCode) usd_mesh.GetPrim().CreateAttribute(attributesTokens[1], Sdf.ValueTypeNames.Float3Array).Set(disp_fc[i].data, timeCode) usd_mesh.GetPrim().CreateAttribute(attributesTokens[2], Sdf.ValueTypeNames.Float3Array).Set(stress_fc[i].data, timeCode) usd_mesh.GetPrim().CreateAttribute(attributesTokens[3], Sdf.ValueTypeNames.Float3Array).Set(vel_fc[i].data, timeCode) # Fill vertices, indices and faces arrays vertices = [] # fills vertices curCoord = coord_fc[i].data for nodeIdx in nodeIndices: vertices.append(curCoord[nodeIdx]) # Create vertices usd_mesh.GetPointsAttr().Set(vertices, timeCode) def export(): # create a new stage stage = Usd.Stage.CreateInMemory('dpf_dyna_ov.usd') # convert create_dpf_prim_with_stage(r"\LS-DYNA\RESULTS\PATH\d3plot", "/d3plot", stage) # save the stage in the end stage.GetRootLayer().Export(r"\Output\path\dpf_dyna_ov.usda") # Entry point if __name__ == '__main__': export()
2