Field and Field Containers Overview

Overview of the usage of fields and field containers in DPF.

The field is the main simulation data container. In numerical simulations, results data are defined by values associated to entities (scoping), and these entities are a subset of a model (support).

In DPF, field data is always associated to its scoping and support, making the field a self-describing piece of data. A field is also defined by its dimensionnality, unit, location, etc. A field can for example, describe a displacement vector or norm, stresses and strains tensors, stresses and strains equivalent, or the minimum and maximum over time of any result. It can be defined on a complete model or just on 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, displacement will have 3 components, a symmetrical stress matrix will have 6.

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

import numpy as np

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

First, create a model object to establish a connection with an example result file and then extract

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

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)

Out:

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)

Out:

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

Extracting 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)

Out:

[[-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, realize that 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 will lead to inefficient operations on large models. Instead, 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)

# Which all yield an identical result as:
print(np.max(field.data, axis=0))

Out:

[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)

Out:

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

Including the Node IDs of the maximum displacements:

print('Node IDs of maximum X, Y, and Z displacement:', max_field.scoping.ids)

Out:

Node IDs of maximum X, Y, and Z displacement: [75, 16, 40]

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

Gallery generated by Sphinx-Gallery