How to use dpf to grab stress results from a multi-step SMART crack growth analysis?

John C
John C Member Posts: 9
Name Dropper First Comment
**

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.

Tagged:

Best Answer

  • Jimmy He
    Jimmy He Member, Employee Posts: 24
    10 Comments 5 Likes First Answer First Anniversary
    ✭✭✭✭
    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()
    

Answers

  • John C
    John C Member Posts: 9
    Name Dropper First Comment
    **

    Thanks @Jimmy He

    This looks like exactly the process I need. The "CreateMeshData()" command and the conversion to a dpf mesh are the steps that I couldn't figure out.

    I will check the process when I'm back in the office and will then mark the question as answered.