Fields container and fields#

字段容器和字段

DPF 使用运算符来加载和操作数据,而使用字段容器和字段来存储和返回数据。换句话说,运算符就像动词,作用于数据;而字段容器和字段就像名词,是保存数据的对象。

Access a fields container or field#

访问字段容器或字段

运算符的输出可以是 ansys.dpf.core.fields_container.FieldsContaineransys.dpf.core.field.Field 类。

字段容器相当于 DPF 的字段列表。它包含一个字段向量。

此示例使用 elastic_strain 运算符访问字段容器:

from ansys.dpf import core as dpf
from ansys.dpf.core import examples
model = dpf.Model(examples.find_msup_transient())
epel = model.results.elastic_strain.on_all_time_freqs
fields = epel.eval()
print(fields)
DPF elastic_strain(s)Fields Container
  with 20 field(s)
  defined on labels: time

  with:
  - field 0 {time:  1} with ElementalNodal location, 6 components and 40 entities.
  - field 1 {time:  2} with ElementalNodal location, 6 components and 40 entities.
  - field 2 {time:  3} with ElementalNodal location, 6 components and 40 entities.
  - field 3 {time:  4} with ElementalNodal location, 6 components and 40 entities.
  - field 4 {time:  5} with ElementalNodal location, 6 components and 40 entities.
  - field 5 {time:  6} with ElementalNodal location, 6 components and 40 entities.
  - field 6 {time:  7} with ElementalNodal location, 6 components and 40 entities.
  - field 7 {time:  8} with ElementalNodal location, 6 components and 40 entities.
  - field 8 {time:  9} with ElementalNodal location, 6 components and 40 entities.
  - field 9 {time:  10} with ElementalNodal location, 6 components and 40 entities.
  - field 10 {time:  11} with ElementalNodal location, 6 components and 40 entities.
  - field 11 {time:  12} with ElementalNodal location, 6 components and 40 entities.
  - field 12 {time:  13} with ElementalNodal location, 6 components and 40 entities.
  - field 13 {time:  14} with ElementalNodal location, 6 components and 40 entities.
  - field 14 {time:  15} with ElementalNodal location, 6 components and 40 entities.
  - field 15 {time:  16} with ElementalNodal location, 6 components and 40 entities.
  - field 16 {time:  17} with ElementalNodal location, 6 components and 40 entities.
  - field 17 {time:  18} with ElementalNodal location, 6 components and 40 entities.
  - field 18 {time:  19} with ElementalNodal location, 6 components and 40 entities.
  - field 19 {time:  20} with ElementalNodal location, 6 components and 40 entities.

Access fields within a fields container#

访问字段容器内的字段

访问字段容器中的字段有很多方法。前面的结果包含一个瞬态结果,这意味着字段容器按时间设置了一个字段。

访问字段:

len(fields)
20

根据索引访问字段:

field_first_time = fields[0]
field_last_time = fields[19]

根据时间集 ID 访问字段:

field = fields.get_field_by_time_id(1)

要访问更复杂请求的字段,可以使用带有请求字段 ID 的 get_field() 方法:

field = fields.get_field({'time': 1})
print(field)
DPF elastic_strain_0.01s Field
Location: ElementalNodal
Unit:
40 entities
Data: 6 components and 320 elementary data
Elemental
IDs                   data ()
------------         ----------
21                   -5.0964e-07   -5.8226e-07    1.8660e-06    8.3252e-09   -3.3062e-09   -7.7246e-08
                     -5.7021e-07   -5.7104e-07    1.8996e-06   -9.9354e-10   -3.4486e-08   -7.4886e-08
                     -6.0495e-07   -6.0408e-07    2.0172e-06    4.9817e-09   -5.5109e-09   -2.1038e-08
                  ...
22                   -5.0964e-07   -5.8226e-07    1.8660e-06   -8.3252e-09   -3.3062e-09    7.7246e-08
                     -5.6697e-07   -6.1112e-07    1.9950e-06    4.0239e-09    1.0457e-09    1.9740e-08
                     -6.0495e-07   -6.0408e-07    2.0172e-06   -4.9817e-09   -5.5109e-09    2.1038e-08
                  ...
23                   -3.7887e-07   -4.8075e-07    1.4980e-06    9.6495e-09   -1.1785e-08   -1.6389e-07
                     -4.6401e-07   -4.6508e-07    1.5451e-06    1.6581e-09   -7.7990e-08   -1.5638e-07
                     -5.7202e-07   -5.7104e-07    1.9081e-06    4.9200e-09   -3.3430e-08   -8.2869e-08
                  ...
...

这里有更实际的例子:

model = dpf.Model(examples.download_all_kinds_of_complexity())
epel = model.results.elastic_strain.on_all_time_freqs.split_by_shape
fields = epel.eval()
field = fields.get_field({'time': 1, 'elshape':0})
print(field)

field = fields.get_field({'time': 1, 'elshape':1})
print(field)
DPF elastic_strain_1.s_elshape:0 Field
Location: ElementalNodal
Unit:
203 entities
Data: 6 components and 2436 elementary data
Elemental
IDs                   data ()
------------          ----------
10791                  9.961283e-05   -1.557876e-05   -6.798322e-05    4.423883e-20    7.823432e-21    4.348549e-06
                       9.532236e-05   -1.426944e-05   -6.635107e-05    4.234001e-20    1.050099e-20    1.901931e-05
                       8.607592e-05   -3.046389e-05   -2.422499e-05    3.823384e-20    1.776519e-20    1.917663e-05
                   ...
10790                  9.829979e-05   -8.944115e-06   -8.014052e-05   -5.813971e-21    3.947791e-20    2.315096e-05
                       9.230295e-05   -1.569666e-05   -6.043398e-05   -6.588927e-21    3.371362e-20    2.682668e-05
                       1.068346e-04   -1.988030e-05   -6.647159e-05   -6.227784e-21    3.825956e-20    2.475124e-05
                   ...
10785                  8.480231e-05   -1.470483e-05   -5.494706e-05    2.105046e-21    3.093755e-20   -9.940667e-06
                       7.555470e-05   -2.958404e-05   -1.549013e-05    2.273083e-21    2.002334e-20   -1.064724e-05
                       7.552039e-05   -2.970292e-05   -1.521445e-05    4.916594e-21    1.996089e-20   -2.255241e-05
                   ...
...
DPF elastic_strain_1.s_elshape:1 Field
Location: ElementalNodal
Unit:
9052 entities
Data: 6 components and 37580 elementary data
Elemental
IDs                   data ()
------------          ----------
1                     -2.365747e-04    8.205943e-04   -2.195325e-04    4.799285e-04    2.372855e-04   -8.473678e-06
                      -5.085632e-04    1.070203e-03   -2.770476e-04   -2.848311e-04    3.473931e-04    4.251066e-06
                      -4.331823e-04    9.600782e-04   -4.320994e-04   -3.780877e-04   -3.978023e-04   -2.898742e-06
                   ...
8                     -2.388557e-04    8.369775e-04   -2.127467e-04    4.718478e-04    1.823031e-04   -5.630592e-06
                      -2.600095e-04    7.688167e-04   -1.320574e-04    5.460561e-04    8.167552e-05   -7.558865e-06
                      -5.470272e-04    9.995268e-04   -1.715976e-04   -3.155533e-04    1.211339e-04   -1.600466e-06
                   ...
15                    -2.588085e-04    7.750597e-04   -1.346239e-04    5.428307e-04    6.121315e-05   -6.311711e-06
                      -2.671824e-04    7.798763e-04   -1.107667e-04    5.587949e-04   -2.850134e-05    1.501269e-06
                      -5.611221e-04    1.008660e-03   -1.391484e-04   -3.172989e-04   -2.487912e-05    1.011503e-07
                   ...
...

下面的示例引用了可用的时间频率支持,以确定字段容器中可用的时间 ID:

model = dpf.Model(examples.find_msup_transient())
epel = model.results.elastic_strain.on_all_time_freqs
fields = epel.eval()
print(fields.time_freq_support)
DPF  Time/Freq Support:
  Number of sets: 20
Cumulative     Time (s)       LoadStep       Substep
1              0.010000       1              1
2              0.020000       1              2
3              0.030000       1              3
4              0.040000       1              4
5              0.050000       1              5
6              0.060000       1              6
7              0.070000       1              7
8              0.080000       1              8
9              0.090000       1              9
10             0.100000       1              10
11             0.110000       1              11
12             0.120000       1              12
13             0.130000       1              13
14             0.140000       1              14
15             0.150000       1              15
16             0.160000       1              16
17             0.170000       1              17
18             0.180000       1              18
19             0.190000       1              19
20             0.200000       1              20

请注意,所用的时间设置 ID 是以 1 为基准的。当通过 fields[0] 使用 Pythonic 索引进行索引时,可以使用从零开始的索引。在使用 get_fields() 方法访问结果时,你应该基于时间范围设置 ID 来构建请求。

Field data#

字段数据

ansys.dpf.core.field.Field 类是 DPF 中数据的基本单位。它包含实际数据及其元数据,即由与实体(范围)相关的值定义的结果数据。这些实体是模型(支持)的子集。

在DPF中,字段数据总是与其作用域和支持相关联,使字段成为自描述的数据块。字段还由其他属性定义,包括维度、单位和位置等等。

../_images/field.png

您可以通过打印字段来了解字段元数据的总体情况:

field = fields[0]
print(field)
DPF elastic_strain_0.01s Field
Location: ElementalNodal
Unit:
40 entities
Data: 6 components and 320 elementary data
Elemental
IDs                   data ()
------------          ----------
21                    -5.096470e-07   -5.822648e-07    1.866023e-06    8.325266e-09   -3.306256e-09   -7.724631e-08
                      -5.702127e-07   -5.710485e-07    1.899680e-06   -9.935434e-10   -3.448644e-08   -7.488671e-08
                      -6.049504e-07   -6.040822e-07    2.017216e-06    4.981728e-09   -5.510947e-09   -2.103890e-08
                   ...
22                    -5.096470e-07   -5.822648e-07    1.866023e-06   -8.325266e-09   -3.306259e-09    7.724629e-08
                      -5.669729e-07   -6.111289e-07    1.995080e-06    4.023948e-09    1.045763e-09    1.974096e-08
                      -6.049504e-07   -6.040822e-07    2.017216e-06   -4.981728e-09   -5.510943e-09    2.103889e-08
                   ...
23                    -3.788760e-07   -4.807594e-07    1.498000e-06    9.649583e-09   -1.178512e-08   -1.638991e-07
                      -4.640120e-07   -4.650817e-07    1.545128e-06    1.658194e-09   -7.799093e-08   -1.563803e-07
                      -5.720271e-07   -5.710485e-07    1.908120e-06    4.920075e-09   -3.343032e-08   -8.286970e-08
                   ...
...

下一节提供了与字段本身相关的元数据的概述。

Field metadata#

字段元数据

字段包含与之关联的结果的元数据。元数据包括位置(如 ElementalNodalElementalNodal )以及与该位置相关联的 ID。

字段的范围定义了数据的顺序,例如, scoping 中的第一个 ID 标识了数据向量中的第一个 entity data 所属的实体。

要访问字段的范围,请使用 scoping 属性:

print(field.scoping)
print('field.scoping.ids:', field.scoping.ids)
print('field.location:', field.location)
 DPF scoping:
   with Elemental location and 40 entities

field.scoping.ids: [21,
  22,
  23,
  24,
  25,
  26,
  ...
  ]

  field.location:'ElementalNodal'
  • Elemental 位置表示每个单元的一个数据值(乘以组件数)。

  • Nodal 位置为每个节点一个值。

  • ElementalNodal 位置是每个单元每个节点一个值。例如,应变是一个 ElementalNodal 值,因为应变是在每个单元的每个节点上评估的。

字段还包含元数据,包括存储数据的形状、字段位置、组件数量和数据单位:

stress = model.results.stress
field = stress.eval()[0]

# Units of the field describing volume
field.unit

#Location of the field (Elemental, ElementalNodal, or Nodal)
field.location

# Number of components associated with the field. It's expected to
# be a single dimension because there can only be one volume per
# element.
field.component_count
'Pa'
'ElementalNodal'
6

Access field data#

访问字段数据

当 DPF-Core 返回 ansys.dpf.core.field.Field 类时,Python 实际上拥有的是该字段的客户端表示,而不是字段本身的全部内容。 这意味着该字段的所有数据都存储在 DPF 服务中。 这一点非常重要,因为在构建后处理工作流程时,与结果数据交互的最有效方式是通过使用运算符或只访问所需的数据,尽量减少 Python 和 DPF 之间的数据交换。

字段的 data 根据其 scoping ids 排序(见上文)。要以 numpy 数组的形式访问整个数据数组,请执行以下操作:

array = field.data
print(array)
DPFArray([[ 4.01372930e+04,  3.85071930e+02, -1.40019130e+07,
        7.48472351e+02, -2.60259531e+04, -2.62856938e+05],
      [-1.19228638e+03, -6.18210815e+02, -1.39912700e+07,
        2.61468994e+03, -1.31871719e+05, -2.59527125e+05],
      [ 9.02558960e+02,  5.63793152e+02, -1.17102740e+07,
       -8.99381836e+02, -1.21302727e+05, -2.45666328e+05],
      ...,
      [-3.99694531e+04,  1.44622528e+02,  9.62343100e+06,
       -7.09812073e+02, -2.26106621e+04, -2.23155891e+05],
      [-4.31104401e+02, -2.67612732e+02,  9.60954800e+06,
        1.93208755e+02, -1.11580734e+05, -2.24406062e+05],
      [ 5.56899536e+02,  3.88515320e+02,  1.17119880e+07,
       -1.68983887e+03, -1.21768023e+05, -2.41346125e+05]])

该数组具有 6 个基本数据组件(对称张量 XX、YY、ZZ、XY、YZ、XZ)。请注意,该数组是一个真正的、本地的 numpy 数组(由 DPFArray 重载)。

print(type(array))
<class 'ansys.dpf.gate.dpf_array.DPFArray'>

如果需要访问单个节点或单元,可使用 get_entity_data()get_entity_data_by_id() 方法进行请求:

从字段中的第一个单元获取数据。

field.get_entity_data(0)
DPFArray([[ 4.01372930e+04,  3.85071930e+02, -1.40019130e+07,
            7.48472351e+02, -2.60259531e+04, -2.62856938e+05],
          [-1.19228638e+03, -6.18210815e+02, -1.39912700e+07,
            2.61468994e+03, -1.31871719e+05, -2.59527125e+05],
          [ 9.02558960e+02,  5.63793152e+02, -1.17102740e+07,
           -8.99381836e+02, -1.21302727e+05, -2.45666328e+05],
          [ 3.97351055e+04, -2.43928162e+02, -1.17250040e+07,
            6.08324829e+02, -2.46618770e+04, -2.43019891e+05],
          [-4.01372930e+04, -3.85071625e+02,  1.40019130e+07,
            7.48472534e+02, -2.60259531e+04,  2.62856938e+05],
          [ 1.19228601e+03,  6.18211121e+02,  1.39912700e+07,
            2.61468970e+03, -1.31871719e+05,  2.59527125e+05],
          [-9.02558777e+02, -5.63793701e+02,  1.17102740e+07,
           -8.99382568e+02, -1.21302727e+05,  2.45666328e+05],
          [-3.97351016e+04,  2.43927902e+02,  1.17250040e+07,
            6.08326172e+02, -2.46618770e+04,  2.43019891e+05]])

获取 ID 为 10 的单元的数据。

field.get_entity_data_by_id(10)
DPFArray([[ 4.99232031e+04,  1.93570602e+02, -3.08514075e+06,
       -5.48255615e+02, -1.37476562e+04,  1.34827719e+05],
      [ 5.23090469e+04, -1.87847885e+02, -1.98004588e+06,
       -1.12942969e+03, -1.11147285e+04,  1.09223398e+05],
      [-4.90510511e+00, -1.16425255e+02, -1.96296662e+06,
       -5.48878540e+02, -5.48524844e+04,  1.09255164e+05],
      [ 2.63994884e+01,  1.50431015e+02, -3.06906050e+06,
       -1.17046680e+03, -6.76924219e+04,  1.34773391e+05],
      [-4.99232031e+04, -1.93571167e+02,  3.08514075e+06,
       -5.48256836e+02, -1.37476562e+04, -1.34827719e+05],
      [-5.23090469e+04,  1.87848083e+02,  1.98004588e+06,
       -1.12943201e+03, -1.11147295e+04, -1.09223398e+05],
      [ 4.90471840e+00,  1.16423714e+02,  1.96296662e+06,
       -5.48877380e+02, -5.48524844e+04, -1.09255164e+05],
      [-2.63994102e+01, -1.50429443e+02,  3.06906050e+06,
       -1.17046619e+03, -6.76924219e+04, -1.34773391e+05]])

请注意,这将对应于字段内 29 的索引。请注意,范围标识符不是顺序标识符。您可以通过以下方式获取字段中单元 29 的索引:

field.scoping.ids.index(10)
29

在这里,ID 为 10 的单元数据由 8 个对称张量构成。弹性应变在每个单元的每个节点处有一个张量值(单元节点位置)。

To get the displacement on node 3, you would use:

disp = model.results.displacement.eval()[0]
disp.get_entity_data_by_id(3)
DPFArray([[8.06571808e-14, 4.03580652e-04, 2.61804706e-05]])

一个 3D 矢量(X、Y、Z)位移

虽然在请求几个单元或节点的数据时可以使用这些方法,但在循环整个数组时就不应该使用了。为了提高效率,在发送大量请求之前,可以在本地恢复一个字段的数据:

with field.as_local_field() as f:
    for i in range(1,100):
        f.get_entity_data_by_id(i)

Operate on field data#

操作字段数据

很多时候,您并不需要在 Python 中直接操作数组的数据。例如,如果您想知道数据的最大值,可以使用 numpy 包中的 array.max() 方法来计算数组的最大值。 不过,这需要将整个数组发送到 Python,然后在那里计算最大值。 与其在 Python 中复制数组并计算最大值,不如直接从字段本身计算最大值。

此示例使用 min_max 运算符计算字段的最大值,同时返回字段:

计算 DPF 中字段的最大值,并将结果以 numpy 数组形式返回。

max_field = field.max()
max_field.data
DPFArray([22083762.  , 22406040.  , 52603044.  ,  1623704.25,  2443320.75,
       5014283.5 ])

获取单元或节点 ID 的最大值。

max_field.scoping.ids
DPFArray([39, 39, 39, 40, 39, 39])

本例使用 elemental_mean 运算符计算字段的平均值:

from ansys.dpf.core import operators as ops
avg_op = ops.averaging.elemental_mean(field)
avg_field = avg_op.outputs.field()
print(avg_field.get_entity_data(0))
print(avg_field.location)
[[ 4.65393066e-04 -2.47955322e-05  0.00000000e+00  7.68026390e+02
  -7.59655688e+04  0.00000000e+00]]
Elemental

有关链式运算符的全面信息,请参阅 Operators

API reference#

有关更多信息,参见 API reference 中的 ref_fields_containerref_field