How to use dpf to grab stress results from a multi-step SMART crack growth analysis?
I have undertaken an automated crack growth analysis using the SMART tool, which gives a result with multiple time points (where each time point is for the different crack length). The multiple steps are viewable through the GUI with no issues.
I would like to access a particular time point using dpf to grab the stress field for subsequent post-processing.
The key part of the code is as given below. ("dataSource_static" is defined elsewhere and is just the pointer to my results file).
my_time_scoping = dpf.Scoping() my_time_scoping.Ids = [1] Stress1 = dpf.operators.result.stress_X(data_sources=dataSource_static) Stress1.inputs.time_scoping.Connect(my_time_scoping) Stress1.outputs.fields_container.GetData()[0]
The above code works fine for the first time point only (ie result set 1) and shows the dpf result details upon execution. If the scoping Id is changed to set 2 or any other time point, then the error below is given.
_
SX:0<-component_selector_fc:2<-S:1<-to_nodal_fc:13<-mapdl::rst::S:10<-mapdl::rst::S<-Unknown exception occurred. Failed to read mapdl::rst::S from rst file., failed to read element nodal component stresses from rst file._
This code works fine for a standard static analysis with multiple time steps, but does not work for the SMART analysis. I presume this is something to do with the mesh being changed for each time step beyond the first point.
Does anyone know how to work around this issue (via dpf or other results reader)?
Thanks.
Best Answer
-
This can be done by combining the ACT result reader with DPF. Below is an example that gets the X component of the normal stress at all time steps and export to vtk for post processing. Alternatively, we can also leverage DPF operators to query the stress at any points within the domain.
import wbjn import mech_dpf import Ans.DataProcessing as dpf import os mech_dpf.setExtAPI(ExtAPI) userdir = wbjn.ExecuteCommand(ExtAPI,"""returnValue(GetUserFilesDirectory())""") analysis = DataModel.AnalysisList[0] rst = DataModel.AnalysisList[0].ResultFileName model = dpf.Model(rst) times = list( model.TimeFreqSupport.TimeFreqs.Data ) n_ts = len(times) for resultSet in range(1,n_ts+1,5): rdr = analysis.GetResultsData() # use ACT reader rdr.CurrentResultSet = resultSet # select preferred result set act_mesh = rdr.CreateMeshData() # read data of the changed mesh for the above result set # Get elemental nodal stress results ele_Ids = act_mesh.ElementIds s_results = rdr.GetResult("S") s_results.SelectComponents(["X"]) s_vals = [ list( s_results.GetElementValues(_) ) for _ in ele_Ids ] # convert ACT mesh to DPF mesh mesh_op = dpf.operators.mesh.acmo_mesh_provider() mesh_op.inputs.assembly_mesh.Connect(dpf.AnsDispatchHolder(act_mesh.InternalObject)) dpf_mesh = mesh_op.outputs.getmeshes_container()[0] dpf_mesh.Unit = "mm" # create a scalar DPF field my_s = dpf.FieldsFactory.CreateScalarField(len(ele_Ids),'ElementalNodal') for eid , s in zip( ele_Ids , s_vals ): my_s.Add( eid , s ) my_s.MeshedRegionSupport = dpf_mesh sX = dpf.FieldsContainerFactory.OverTimeFreqFieldsContainer([my_s]) #Extend stress result also to mid side nodes mid_op = dpf.operators.averaging.extend_to_mid_nodes_fc() mid_op.inputs.fields_container.Connect(sX) s_field_corner_mid = mid_op.outputs.fields_container.GetData() # Average to node op = dpf.operators.averaging.elemental_nodal_to_nodal_fc() # operator instantiation op.inputs.fields_container.Connect(s_field_corner_mid) op.inputs.extend_to_mid_nodes.Connect(True)# optional s_field_nodal = op.outputs.fields_container.GetData() # Save to vtk op = dpf.operators.serialization.vtk_export() # operator instantiation op.inputs.file_path.Connect(out_dir+'/vol.vtk') op.inputs.mesh.Connect(dpf_mesh)# optional op.inputs.fields1.Connect(s_field_nodal) op.Run()
1