Operators Overview

Overview of the usage of operators in DPF.

Operators are primary method for interacting with and extracting results. Within DPF-Core, these operators are directly exposed with the Operators class as well as wrapped within several other convenience classes.

This example demonstrates how to work directly with operators and compares it to wrapped approach.

For a full listing of all available operators, please see Operators.

from ansys.dpf import core as dpf
from ansys.dpf.core import examples

First, create a model object to establish a connection with an example result file.

model = dpf.Model(examples.static_rst)
print(model)

Out:

DPF Model
------------------------------
DPF Result Info
  Analysis: static
  Physics Type: mecanic
  Unit system: MKS: m, kg, N, s, V, A, degC
  Available results:
    U Displacement :nodal displacements
    RF Force :nodal reaction forces
    S Stress :element nodal component stresses
    ENG_VOL Volume :element volume
    ENG_SE Energy-stiffness matrix :element energy associated with the stiffness matrix
    ENG_AHO Hourglass Energy :artificial hourglass energy
    ENG_TH thermal dissipation energy :thermal dissipation energy
    ENG_KE Kinetic Energy :kinetic energy
    ENG_CO co-energy :co-energy (magnetics)
    ENG_INC incremental energy :incremental energy (magnetics)
    EPEL Strain :element nodal component elastic strains
    BFE Temperature :element structural nodal temperatures
------------------------------
DPF  Meshed Region:
  81 nodes
  8 elements
  Unit: m
  With solid (3D) elements
------------------------------
DPF  Time/Freq Support:
  Number of sets: 1
Cumulative     Time (s)       LoadStep       Substep
1              1.000000       1              1

Next, create a raw displacement operator "U". Each operator contains input and output pins that can be connected to various sources, to include other operators. This allows operators to be “chained” to allow for highly efficient operations.

Here, we print out the available inputs and outputs of the displacement operator.

disp_op = dpf.Operator('U')
print(disp_op.inputs)
print(disp_op.outputs)

Out:

Available inputs:
     -   fields_container : FieldsContainer, optional
         Fields container already allocated modified inplace

     -   mesh : MeshedRegion, MeshesContainer, optional
         Prevents from reading the mesh in the result files

     -   time_scoping : Scoping, int, list, float, Field, optional
         Time/freq (use doubles or field), time/freq set ids (use ints or
         scoping) or time/freq step ids (use scoping with timefreq_steps
         location) requiered in output

     -   bool_rotate_to_global : bool, optional
         If true the field is rotated to global coordinate system (default
         true)

     -   mesh_scoping : ScopingsContainer, Scoping, optional
         Nodes or elements scoping requiered in output. the scoping's location
         indicates whether nodes or elements are asked. using scopings
         container enables to split the result fields container in domains

     -   streams_container : StreamsContainer, optional
         Result file container allowed to be kept open to cache data

     -   data_sources : DataSources
         Result file path container, used if no streams are set

     -   read_cyclic : Enum Dataprocessing::Ecyclicreading, int, optional
         If 0 cyclic symmetry is ignored, if 1 cyclic sector is read, if 2
         cyclic expansion is done, if 3 cyclic expansion is done and stages are
         merged (default is 1)


Available outputs:
     -   fields_container

Compute the Maximum Normalized Displacement

Here, connect the input of the operator to the data sources contained within the model object and then the maximum of the norm of the operator to demonstrate how to chain various operators.

# connect to the data sources of the model
disp_op.inputs.data_sources.connect(model.metadata.data_sources)

# Create a field container norm operator and connect it to the
# displacement operator to chain the operators.
norm_op = dpf.Operator('norm_fc')
norm_op.inputs.connect(disp_op.outputs)

# create a field container min/max operator and connect it to the
# output of the norm operator
mm_op = dpf.Operator('min_max_fc')
mm_op.inputs.connect(norm_op.outputs)

# Finally, get the value of the maximum displacement
field_max = mm_op.outputs.field_max()
print(field_max)
print(field_max.data)

Out:

DPF displacement_1.s Field
  Location: Nodal
  Unit: m
  1 entities
  Data:1 components and 1 elementary data

[1.48153706e-08]

Wrapped Operators

The model.results property contains all the wrapped operators available for a given result. This is provided out of convenience as not all operators may be available for a given result and it is much easier to reference available operators by first running:

print(model.results)

Out:

DPF Result Info
  Analysis: static
  Physics Type: mecanic
  Unit system: MKS: m, kg, N, s, V, A, degC
  Available results:
    U Displacement :nodal displacements
    RF Force :nodal reaction forces
    S Stress :element nodal component stresses
    ENG_VOL Volume :element volume
    ENG_SE Energy-stiffness matrix :element energy associated with the stiffness matrix
    ENG_AHO Hourglass Energy :artificial hourglass energy
    ENG_TH thermal dissipation energy :thermal dissipation energy
    ENG_KE Kinetic Energy :kinetic energy
    ENG_CO co-energy :co-energy (magnetics)
    ENG_INC incremental energy :incremental energy (magnetics)
    EPEL Strain :element nodal component elastic strains
    BFE Temperature :element structural nodal temperatures

Create the displacement operator directly from the results property

disp_op = model.results.displacement()

# Out of convenience, the operators module contains available operators
# Those operators can be created in chain to create a workflow in one line
from ansys.dpf.core import operators
mm_op = operators.min_max.min_max_fc(operators.math.norm_fc(disp_op))

# Finally, get the value of the maximum displacement.
field_max = mm_op.outputs.field_max()
print(field_max)
print(field_max.data)

Out:

DPF displacement_1.s Field
  Location: Nodal
  Unit: m
  1 entities
  Data:1 components and 1 elementary data

[1.48153706e-08]

Plot the displacement

print(model.metadata.meshed_region.plot(disp_op.outputs.fields_container()))
01 basic operators

Out:

[(0.0729555495773441, 0.1029555495773441, 0.0729555495773441),
 (0.015, 0.045, 0.015),
 (0.0, 0.0, 1.0)]

Scripting operators syntax

DPF is also providing a scripting syntax where knowing the operator “string name” is not mandatory. Here is a similar script as above using this syntax.

Instead of using a model class instance, let’s directly use a datasources object. The DataSources constructor input is a path.

ds = dpf.DataSources(examples.static_rst)
print(examples.static_rst)

Out:

c:\hostedtoolcache\windows\python\3.8.10\x64\lib\site-packages\ansys\dpf\core\examples\static.rst

Let’s instantiate the operators and connect them together.

disp_op = dpf.operators.result.displacement()
disp_op.inputs.data_sources.connect(ds)
norm_op = dpf.operators.math.norm_fc()
norm_op.inputs.connect(disp_op.outputs)
mm_op = dpf.operators.min_max.min_max_fc()
mm_op.inputs.connect(norm_op.outputs)

Let’s get the output and print the result data.

field_max = mm_op.outputs.field_max()
print(field_max.data)

Out:

[1.48153706e-08]

Total running time of the script: ( 0 minutes 1.613 seconds)

Gallery generated by Sphinx-Gallery