How can I plot results generated by a conditional equation using a Python Result object?

Nikos Kallitsis
Nikos Kallitsis Member, Employee Posts: 40
10 Comments 5 Likes First Anniversary Ansys Employee
✭✭✭✭

In my Mechanical Model, I need to plot values at each node based on the following conditional equation:

delta = (SX + SY + SZ) / SEQV

if delta >= 0:
rV = EPTO_EQV / (a0 + b0 ** (c*delta))

if delta < 0:
rV = b0

This cannot be achieved using the standard User Defined Result object in Mechanical, as it does not support conditional statements. Importing post-processed data and plotting them with a User Defined Result would only provide values for a single time point.

Is there a way to accomplish this using DPF with a Python Result object?

Best Answer

  • Nikos Kallitsis
    Nikos Kallitsis Member, Employee Posts: 40
    10 Comments 5 Likes First Anniversary Ansys Employee
    ✭✭✭✭
    Answer ✓

    You can use the following script:

    def post_started(sender, analysis):# Do not edit this line
        define_dpf_workflow(analysis)
    
    # Uncomment this function to enable retrieving results from the table/chart
    # def table_retrieve_result(value):# Do not edit this line
        # import mech_dpf
        # import Ans.DataProcessing as dpf
        # wf = dpf.Workflow(this.WorkflowId)
        # wf.Connect('contour_selector', value)
        # this.Evaluate()
    
    def define_dpf_workflow(analysis):
        import mech_dpf
        import Ans.DataProcessing as dpf
        import math
    
        mech_dpf.setExtAPI(ExtAPI)
    
        # Get components from field container
        def get_field_container(field_container, index):
    
            op = dpf.operators.logic.component_selector_fc()
            op.inputs.fields_container.Connect(field_container)
            op.inputs.component_number.Connect(index)
            my_fields_container = op.outputs.fields_container.GetData()
    
            return my_fields_container
    
        #Get path to result file
        analysis = ExtAPI.DataModel.Project.Model.Analyses[0]
        filepath = analysis.ResultFileName
    
        #Data sources
        dataSources = dpf.DataSources()
        dataSources.SetResultFilePath(filepath)
    
        # Model
        model=dpf.Model(dataSources)
    
        # Equivalent Plastic Strain result
        epto_op = dpf.operators.result.plastic_strain_eqv()
        epto_op.inputs.data_sources.Connect(dataSources)
        epto_op.inputs.requested_location.Connect('ElementalNodal')
    
        epto_fc = epto_op.outputs.fields_container.GetData()
    
        # Equivalent Stress result
        seqv_op = dpf.operators.result.stress_eqv_as_mechanical()
        seqv_op.inputs.data_sources.Connect(dataSources)
        seqv_op.inputs.requested_location.Connect('ElementalNodal')
    
        seqv_fc = seqv_op.outputs.fields_container.GetData()
    
        # Stress results
        s_op = dpf.operators.result.stress()
        s_op.inputs.data_sources.Connect(dataSources)
        s_op.inputs.requested_location.Connect('ElementalNodal')
    
        s_fc = s_op.outputs.fields_container.GetData()
    
        # Field Containers
        epto = get_field_container(epto_fc, 0)[0]
        seqv = get_field_container(seqv_fc, 0)[0]
        sX = get_field_container(s_fc, 0)[0]
        sY = get_field_container(s_fc, 1)[0]
        sZ = get_field_container(s_fc, 2)[0]
    
        # Constants for equation
        a0 = 1
        b0 = 2
        c = 3
    
        # Application of conditional equation
        resVal = []
        num_ent = epto.ScopingIds.Count
    
        for i in range(num_ent):
    
            epto_Data = epto.GetEntityDataByIndex(i)
            seqv_Data = seqv.GetEntityDataByIndex(i)
            sX_Data = sX.GetEntityDataByIndex(i)
            sY_Data = sY.GetEntityDataByIndex(i)
            sZ_Data = sZ.GetEntityDataByIndex(i)
    
            resVal_Data = []
    
            for j in range(len(epto_Data)):
    
                delta = (sX_Data[j] + sY_Data[j] + sZ_Data[j]) / seqv_Data[j]
    
                if delta >= 0:
    
                    rV = epto_Data[j] / (a0 + b0 ** (c*delta))
    
                else:
    
                    rV = b0
    
                resVal_Data.append(rV)
    
            resVal.append(resVal_Data)
    
        resVal_field = dpf.FieldsFactory.CreateScalarField(num_ent,'ElementalNodal')
        [resVal_field.Add(id = seqv.ScopingIds[i], data = resVal[i]) for i in range(num_ent)]
    
        # Plotting
        output = dpf.operators.utility.forward()
        output.inputs.any.Connect(resVal_field)
    
        dpf_workflow = dpf.Workflow()
        dpf_workflow.Add(output)
        dpf_workflow.SetOutputContour(output)
        dpf_workflow.Record('wf_id', False)
        this.WorkflowId = dpf_workflow.GetRecordedId()
    

    Instead of ElementalNodal you can also request Nodal location.