Field and field containers overview#

In DPF, the field is the main simulation data container. During a numerical simulation, the result data is defined by values associated to entities (scoping). These entities are a subset of a model (support).

Because the field data is always associated to its scoping and support, the field is a self-describing piece of data. A field is also defined by its parameters, such as dimensionality, unit, and location. For example, a field can describe any of the following:

  • Displacement vector

  • Norm, stress, or strain tensor

  • Stress or strain equivalent

  • Minimum or maximum over time of any result.

A field can be defined on a complete model or on only certain entities of the model based on its scoping. The data is stored as a vector of double values, and each elementary entity has a number of components. For example, a displacement has three components, and a symmetrical stress matrix has six components.

In DPF, a fields container is simply a collection of fields that can be indexed, just like a Python list. Operators applied to a fields container have each individual field operated on. Fields containers are outputs from operators.

# First, import necessary modules
import numpy as np

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

Create a model object to establish a connection with an example result file and then extract:

model = dpf.Model(examples.find_static_rst())
print(model)
DPF Model
------------------------------
Static analysis
Unit system: MKS: m, kg, N, s, V, A, degC
Physics Type: Mechanical
Available results:
     -  displacement: Nodal Displacement
     -  reaction_force: Nodal Force
     -  stress: ElementalNodal Stress
     -  elemental_volume: Elemental Volume
     -  stiffness_matrix_energy: Elemental Energy-stiffness matrix
     -  artificial_hourglass_energy: Elemental Hourglass Energy
     -  thermal_dissipation_energy: Elemental thermal dissipation energy
     -  kinetic_energy: Elemental Kinetic Energy
     -  co_energy: Elemental co-energy
     -  incremental_energy: Elemental incremental energy
     -  elastic_strain: ElementalNodal Strain
     -  element_euler_angles: ElementalNodal Element Euler Angles
     -  structural_temperature: ElementalNodal Structural temperature
------------------------------
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

Create the displacement operator directly from the results property and extract the displacement fields container:

disp_op = model.results.displacement()
fields = disp_op.outputs.fields_container()
print(fields)
DPF displacement(s)Fields Container
  with 1 field(s)
  defined on labels: time

  with:
  - field 0 {time:  1} with Nodal location, 3 components and 81 entities.

A field can be extracted from a fields container by simply indexing the requested field:

field = fields[0]
print(field)
DPF displacement_1.s Field
  Location: Nodal
  Unit: m
  81 entities
  Data: 3 components and 81 elementary data

  Nodal
  IDs                   data(m)
  ------------          ----------
  1                     -3.319046e-22  -6.935660e-09  -3.286174e-22

  26                    2.230265e-09   -7.142140e-09  -2.920779e-22

  14                    0.000000e+00   0.000000e+00   0.000000e+00

  ...

Extract data from a field#

You can extract all the data from a given field using the data property. This returns a numpy array.

print(field.data)
[[-3.31904602e-22 -6.93565975e-09 -3.28617350e-22]
 [ 2.23026491e-09 -7.14214033e-09 -2.92077883e-22]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-3.01173895e-22 -7.14214033e-09 -2.23026491e-09]
 [ 2.09077164e-09 -7.33058082e-09 -2.09077164e-09]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 1.06212713e-09 -6.89858785e-09 -3.77906905e-22]
 [ 1.89019831e-09 -3.34398104e-09  1.43440783e-23]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-2.71912713e-23 -2.92690969e-09 -2.33676924e-23]
 [ 1.01364486e-09 -7.10540890e-09 -2.14726184e-09]
 [ 1.89155604e-09 -3.73823999e-09 -1.89155604e-09]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 7.64096553e-24 -3.34398104e-09 -1.89019831e-09]
 [-3.81104389e-22 -6.89858785e-09 -1.06212713e-09]
 [ 2.14726184e-09 -7.10540890e-09 -1.01364486e-09]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-9.53485079e-23 -7.14214033e-09  2.23026491e-09]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 2.09077164e-09 -7.33058082e-09  2.09077164e-09]
 [ 1.18477336e-22 -3.34398104e-09  1.89019831e-09]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 1.89155604e-09 -3.73823999e-09  1.89155604e-09]
 [ 1.01364486e-09 -7.10540890e-09  2.14726184e-09]
 [-2.61320844e-22 -6.89858785e-09  1.06212713e-09]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [ 2.14726184e-09 -7.10540890e-09  1.01364486e-09]
 [-1.54190337e-21 -1.42766633e-08 -1.53720678e-21]
 [ 2.25103522e-09 -1.43688328e-08 -1.55960665e-21]
 [-1.55180700e-21 -1.43688328e-08 -2.25103522e-09]
 [ 2.25860708e-09 -1.44669483e-08 -2.25860708e-09]
 [-1.02704768e-21 -1.05919802e-08 -1.01743770e-21]
 [ 1.16452955e-09 -1.44002311e-08 -1.52834607e-21]
 [ 2.29356739e-09 -1.07400000e-08 -1.07537743e-21]
 [-1.08050063e-21 -1.07400000e-08 -2.29356739e-09]
 [ 1.16046741e-09 -1.44722939e-08 -2.25762828e-09]
 [ 2.26430754e-09 -1.08989140e-08 -2.26430754e-09]
 [-1.50544246e-21 -1.44002311e-08 -1.16452955e-09]
 [ 2.25762828e-09 -1.44722939e-08 -1.16046741e-09]
 [ 2.25860708e-09 -1.44669483e-08  2.25860708e-09]
 [-1.24684037e-21 -1.43688328e-08  2.25103522e-09]
 [ 2.26430754e-09 -1.08989140e-08  2.26430754e-09]
 [ 1.16046741e-09 -1.44722939e-08  2.25762828e-09]
 [-8.03413897e-22 -1.07400000e-08  2.29356739e-09]
 [ 2.25762828e-09 -1.44722939e-08  1.16046741e-09]
 [-1.35051199e-21 -1.44002311e-08  1.16452955e-09]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-2.23026491e-09 -7.14214033e-09 -9.66448574e-23]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-2.09077164e-09 -7.33058082e-09 -2.09077164e-09]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-1.89019831e-09 -3.34398104e-09  1.19096032e-22]
 [-1.06212713e-09 -6.89858785e-09 -2.59300974e-22]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-1.89155604e-09 -3.73823999e-09 -1.89155604e-09]
 [-1.01364486e-09 -7.10540890e-09 -2.14726184e-09]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-2.14726184e-09 -7.10540890e-09 -1.01364486e-09]
 [-2.09077164e-09 -7.33058082e-09  2.09077164e-09]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-1.01364486e-09 -7.10540890e-09  2.14726184e-09]
 [-1.89155604e-09 -3.73823999e-09  1.89155604e-09]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-2.14726184e-09 -7.10540890e-09  1.01364486e-09]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-2.25103522e-09 -1.43688328e-08 -1.20291800e-21]
 [-2.25860708e-09 -1.44669483e-08 -2.25860708e-09]
 [-2.29356739e-09 -1.07400000e-08 -7.91446544e-22]
 [-1.16452955e-09 -1.44002311e-08 -1.32988359e-21]
 [-2.26430754e-09 -1.08989140e-08 -2.26430754e-09]
 [-1.16046741e-09 -1.44722939e-08 -2.25762828e-09]
 [-2.25762828e-09 -1.44722939e-08 -1.16046741e-09]
 [-2.25860708e-09 -1.44669483e-08  2.25860708e-09]
 [-1.16046741e-09 -1.44722939e-08  2.25762828e-09]
 [-2.26430754e-09 -1.08989140e-08  2.26430754e-09]
 [-2.25762828e-09 -1.44722939e-08  1.16046741e-09]]

While it might seem preferable to work entirely within numpy, DPF runs outside of Python and potentially even on a remote machine. Therefore, the transfer of unnecessary data between the DPF instance and the Python client leads to inefficient operations on large models. Instead, you should use DPF operators to assemble the necessary data before recalling the data from DPF.

For example, if you want the maximum displacement for a given result, use the min/max operator:

min_max_op = dpf.operators.min_max.min_max(field)
print(min_max_op.outputs.field_max().data)

# Out of conveience, you can simply take the max of the field with:
print(field.max().data)

# The above yields a result identical to:
print(np.max(field.data, axis=0))
[2.29356739e-09 0.00000000e+00 2.29356739e-09]
[2.29356739e-09 0.00000000e+00 2.29356739e-09]
[2.29356739e-09 0.00000000e+00 2.29356739e-09]

Note that the numpy array does not retain any information about the field it describes. Using the DPF max operator of the field does retain this information.

max_field = field.max()
print(max_field)
DPF displacement_1.s Field
  Location: Nodal
  Unit: m
  3 entities
  Data: 1 components and 3 elementary data

  IDs                   data(m)
  ------------          ----------
  75                    2.293567e-09

  66                    0.000000e+00

  40                    2.293567e-09

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

Gallery generated by Sphinx-Gallery