Skip to main content

Script Tip Friday - Examples of Python Results for Mechanical (Part 1)

| 12.16.2022

This Script Tip Friday is brought to you by Pernelle Marone-Hitz, Lead Application Engineer at Ansys. Pernelle brings us a tip today that will cover two examples of Python results for Ansys Mechanical.

The Python Result object enables you to evaluate output quantities by executing an Iron-python script based on the Data Processing Framework (DPF) post-processing toolbox. In this post, we will cover two examples of Python Results:

  1. Example 1: Get the maximum over time of the total deformation.
  2. Example 2: Get the average total deformation on all time steps.

Example 1: Maximum Over Time of the Total Deformation

Please note that this result is already available natively in Mechanical: Insert a Total Deformation result and change the “Definition/By” section to “Maximum Over Time”:

In this example, we will “recode” this functionality and show that DPF can be used to create the same result. First, insert a Python Result object:

The chain of operators will be relatively simple:

The Data Source will be the result file: dataSource = dpf.DataSources(analysis.ResultFileName)

It is important to define the Time Scoping appropriately: by default, DPF will operate on the last time step only, and here we want to make sure all the time steps are considered so that for each node we get the maximum value on all the time steps. This can be achieved by checking the number of results sets and selecting them all.

For some operators such as the max_over_time_by_entity that is used here, the result will be a field container without any label. That would cause the Python Result to raise an error. To overcome this, a ‘time’ label should be added to the fields container.

Finally, to plot the results back on the model, the forward_field() method should be used to send the field to an operator to be able to plot it.

The complete script is as follows:

def post_started(sender, analysis):# Do not edit this line
    define_dpf_workflow(analysis)

def define_dpf_workflow(analysis):
    import mech_dpf
    import Ans.DataProcessing as dpf
    mech_dpf.setExtAPI(ExtAPI)
    dataSource = dpf.DataSources(analysis.ResultFileName)

    # Get displacement
    u = dpf.operators.result.displacement()
    u.inputs.data_sources.Connect(dataSource)

    # Set time scoping
    timeScop = dpf.Scoping()
    number_sets = u.outputs.fields_container.GetData().GetTimeFreqSupport().NumberSets
    timeScop.Ids = range(1,number_sets+1)
    u.inputs.time_scoping.Connect(timeScop)

    # Use norm operator to get total deformation
    nrm = dpf.operators.math.norm_fc()
    nrm.Connect(u)

    # Find max over time
    max_over_time = dpf.operators.min_max.max_over_time_by_entity()
    max_over_time.inputs.fields_container.Connect(nrm)
    data_fieldc = max_over_time.outputs.getfields_container()
    data_fieldc.AddLabel('time')

    # Forward to plot
    output = dpf.operators.utility.forward()
    output.inputs.any.Connect(data_fieldc)

    dpf_workflow = dpf.Workflow()
    dpf_workflow.Add(output)
    dpf_workflow.SetOutputContour(output)
    dpf_workflow.Record('wf_id', False)
    this.WorkflowId = dpf_workflow.GetRecordedId()

And we can check that the plot obtained through this method is the same as the one obtained in the standard Mechanical result:

Example 2: Average Total Deformation on All Time Steps

Again, the chain of operators will be quite simple:

The complete script is as follows:

def post_started(sender, analysis):# Do not edit this line
    define_dpf_workflow(analysis)

def define_dpf_workflow(analysis):
    import mech_dpf
    import Ans.DataProcessing as dpf
    mech_dpf.setExtAPI(ExtAPI)
    dataSource = dpf.DataSources(analysis.ResultFileName)

    # displacement operator
    u = dpf.operators.result.displacement()
    u.inputs.data_sources.Connect(dataSource)

    # Set time scoping
    timeScop = dpf.Scoping()
    number_sets = u.outputs.fields_container.GetData().GetTimeFreqSupport().NumberSets
    timeScop.Ids = range(1,number_sets+1)
    u.inputs.time_scoping.Connect(timeScop) 

    # Use norm operator to get total deformation
    nrm = dpf.operators.math.norm_fc()
    nrm.Connect(u)
    nrm_field = nrm.outputs.getfields_container()

    # Compute average
    add_fc = dpf.operators.math.add_fc()
    for i in range(nrm_field.FieldCount):
        add_fc.Connect(i,nrm_field[i])
    avg = dpf.operators.math.scale_fc()
    avg.inputs.fields_container.Connect(add_fc)
    avg.inputs.ponderation.Connect(1/float(nrm_field.FieldCount))
    data_fieldc = avg.outputs.getfields_container()
    data_fieldc.AddLabel('time')

    # Forward to plot
    output = dpf.operators.utility.forward()
    output.inputs.any.Connect(data_fieldc)

    dpf_workflow = dpf.Workflow()
    dpf_workflow.Add(output)
    dpf_workflow.SetOutputContour(output)
    dpf_workflow.Record('wf_id', False)
    this.WorkflowId = dpf_workflow.GetRecordedId()

And the values are plotted back on the model: