Load custom data in DPF#
This tutorial shows how to represent your custom data in DPF data storage structures.
To import you custom data in DPF, you must create a DPF data structure to store it. DPF uses |Field| and |FieldsContainer| objects to handle data. The |Field| is a homogeneous array and a |FieldsContainer| is a labeled collection of |Field|. For more information on DPF data structures such as the |Field| and their use check the DPF data structures tutorials section.
Download tutorial as Python script
Download tutorial as Jupyter notebook
Define the data#
In this tutorial, we create different Fields from data stored in Python lists.
Create the python lists with the data to be set to the Fields.
# Data for the scalar Fields (lists with 1 and 2 dimensions)
data_1 = [6.0, 5.0, 4.0, 3.0, 2.0, 1.0]
data_2 = [[12.0, 7.0, 8.0], [ 9.0, 31.0, 1.0]]
# Data for the vector Fields (lists with 1 and 2 dimensions)
data_3 = [4.0, 1.0, 8.0, 5.0, 7.0, 9.0]
data_4 = [6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 9.0, 7.0, 8.0, 10.0]
data_5 = [[8.0, 4.0, 3.0], [31.0, 5.0, 7.0]]
# Data for the matrix Fields
data_6 = [3.0, 2.0, 1.0, 7.0]
data_7 = [15.0, 3.0, 9.0, 31.0, 1.0, 42.0, 5.0, 68.0, 13.0]
data_8 = [[12.0, 7.0, 8.0], [ 1.0, 4.0, 27.0], [98.0, 4.0, 6.0]]
Create the python lists with the data to be appended to the Fields.
# Data for the scalar Fields
data_9 = [24.0]
# Data for the vector Fields
data_10 = [47.0, 33.0, 5.0]
# Data for the matrix Fields
data_11 = [8.0, 2.0, 4.0, 64.0, 32.0, 47.0, 11.0, 23.0, 1.0]
Create the Fields#
In this tutorial, we explain how to create the following Fields:
Scalar Field;
Vector Field;
Matrix Field.
Note
A |Field| must always be given:
-
Here, we create Fields in the default ‘Nodal’
location. Thus, each entity (here, the nodes) must have a |Scoping| id, that can be defined in a random or in a numerical order: A
natureand adimensionality(number of data components for each entity). They must respect the type and size of the data to be stored in the |Field|.
Import the PyDPF-Core library#
First, import the PyDPF-Core library.
# Import the ``ansys.dpf.core`` module
from ansys.dpf import core as dpf
Define the Fields sizing#
The second step consists in defining the Fields dimensions.
Here, we create one |Field| with 6 scalar. Thus, 6 entities with one |Scoping| id each.
# Define the number of entities
num_entities_1 = 6
You must ensure that this |Field| has a ‘scalar’ nature and an ‘1D’ dimensionality.
Here, we create:
One |Field| with 2 vectors (thus, 2 entities) of 3 components each (3D vector |Field|);
One |Field| with 2 vectors (thus, 2 entities) of 5 components each (5D vector |Field|);
# Define the number of entities
num_entities_2 = 2
You must ensure that these Fields have a ‘vector’ nature and the corresponding dimensionality
(‘3D’ and ‘5D’).
Here, we create:
One Field with 1 matrix (thus, 1 entity) of 2 lines and 2 columns;
Two Fields with 1 matrix (thus, 1 entity) of 3 lines and 3 columns (tensor).
# Define the number of entities
num_entities_3 = 1
You must ensure that these Fields have a ‘matrix’ nature and the corresponding dimensionality.
Create the Fields objects#
You can create the Fields using two approaches:
Create a |Field| by an instance of this object#
# Define the number of entities
num_entities_1 = 6
You must ensure that this |Field| has a ‘scalar’ nature and an ‘1D’ dimensionality.
For this approach, the default nature of the |Field| object is ‘vector’. You can modify it directly with the
‘nature’ argument or with the Field.dimensionality method.
Create the scalar |Field| and use the ‘nature’ argument.
# Instanciate the Field
field_11 = dpf.Field(nentities=num_entities_1, nature=dpf.common.natures.scalar)
# Set the scoping ids
field_11.scoping.ids = range(num_entities_1)
# Print the Field
print("Scalar Field: ", '\n',field_11, '\n')
Scalar Field:
DPF Field
Location: Nodal
Unit:
6 entities
Data: 1 components and 0 elementary data
Create the scalar |Field| and use the Field.dimensionality method.
# Instanciate the Field
field_12 = dpf.Field(nentities=num_entities_1)
# Use the Field.dimensionality method
field_12.dimensionality = dpf.Dimensionality([1])
# Set the scoping ids
field_12.scoping.ids = range(num_entities_1)
# Print the Field
print("Scalar Field : ", '\n',field_12, '\n')
Scalar Field :
DPF Field
Location: Nodal
Unit:
6 entities
Data: 1 components and 0 elementary data
Here, we create:
One |Field| with 2 vectors (thus, 2 entities) of 3 components each (3D vector |Field|);
One |Field| with 2 vectors (thus, 2 entities) of 5 components each (5D vector |Field|);
# Define the number of entities
num_entities_2 = 2
You must ensure that these Fields have a ‘vector’ nature and the corresponding dimensionality (‘3D’ and ‘5D’).
For this approach, the default nature is ‘vector’ and the default dimensionality is ‘3D’. So for the second vector
|Field| you must set a ‘5D’ dimensionality using the Field.dimensionality method.
Create the ‘3D’ vector Field.
# Instantiate the Field
field_21 = dpf.Field(nentities=num_entities_2)
# Set the scoping ids
field_21.scoping.ids = range(num_entities_2)
# Print the Field
print("3D vector Field : ", '\n',field_21, '\n')
3D vector Field :
DPF Field
Location: Nodal
Unit:
2 entities
Data: 3 components and 0 elementary data
Create the ‘5D’ vector Field.
# Instantiate the Field
field_31 = dpf.Field(nentities=num_entities_2)
# Use the Field.dimensionality method
field_31.dimensionality = dpf.Dimensionality([5])
# Set the scoping ids
field_31.scoping.ids = range(num_entities_2)
# Print the Field
print("5D vector Field (5D): ", '\n',field_31, '\n')
5D vector Field (5D):
DPF Field
Location: Nodal
Unit:
2 entities
Data: 5 components and 0 elementary data
Create a |Field| using the fields_factory module#
You can use two functions from the fields_factory module to create a scalar |Field|:
The
create_scalar_field()function;The
field_from_array()function.
Create the Field using the create_scalar_field function
For this approach, the default nature of the |Field| object is ‘scalar’ and the default dimensionality is ‘1D’.
Thus, you just have to use the create_scalar_field() function to create a scalar |Field|.
# Create the scalar Field
field_13 = dpf.fields_factory.create_scalar_field(num_entities=num_entities_1)
# Set the scoping ids
field_13.scoping.ids = range(num_entities_1)
# Print the Field
print("Scalar Field: ", '\n',field_13, '\n')
Scalar Field:
DPF Field
Location: Nodal
Unit:
6 entities
Data: 1 components and 0 elementary data
Create the Field using the field_from_array function
Different from the other approaches, where you set or append the data after creating the |Field|, here, the data is
used as an input of the field_from_array() function.
This function gets an Numpy array or Python list of either:
1 dimension (one array). In this case, you get directly a scalar |Field|;
2 dimensions (one array containing multiple arrays with 3 components each). In the is case, you get a 3D vector |Field|. Thus, you have to change the |Field|
dimensionalityusing theField.dimensionalitymethod.
Create the scalar Field with an 1 dimensional list.
# Use the field_from_array function
field_14 = dpf.fields_factory.field_from_array(arr=data_1)
# Set the scoping ids
field_14.scoping.ids = range(num_entities_1)
# Print the Field
print("Scalar Field: ", '\n',field_14, '\n')
Scalar Field:
DPF Field
Location: Nodal
Unit:
6 entities
Data: 1 components and 6 elementary data
IDs data
------------ ----------
0 6.000000e+00
1 5.000000e+00
2 4.000000e+00
...
Create the scalar Field with a 2 dimensional list.
# Use the field_from_array function
field_15 = dpf.fields_factory.field_from_array(arr=data_2)
# Use the |Field.dimensionality| method
field_15.dimensionality = dpf.Dimensionality([1])
# Set the scoping ids
field_15.scoping.ids = range(num_entities_1)
# Print the Field
print("Scalar Field (b): ", '\n',field_15, '\n')
Scalar Field (b):
DPF Field
Location: Nodal
Unit:
6 entities
Data: 1 components and 6 elementary data
IDs data
------------ ----------
0 1.200000e+01
1 7.000000e+00
2 8.000000e+00
...
You can use three functions from the fields_factory module to create a vector |Field|:
The
create_vector_field()function;The
create_3d_vector_field()function (Specifically to create a 3D vector |Field| (a vector |Field| with 3 components for each entity));The
field_from_array()function.
Create the Field using the create_vector_field() function
For this approach, the default nature is ‘vector’. To define the dimensionality you must use the ‘num_comp’ argument.
Create the ‘3D’ vector Field.
# Use the create_vector_field function
field_22 = dpf.fields_factory.create_vector_field(num_entities=num_entities_2, num_comp=3)
# Set the scoping ids
field_22.scoping.ids = range(num_entities_2)
# Print the Field
print("3D vector Field : ", '\n',field_22, '\n')
3D vector Field :
DPF Field
Location: Nodal
Unit:
2 entities
Data: 3 components and 0 elementary data
Create the ‘5D’ vector Field.
# Use the create_vector_field function
field_32 = dpf.fields_factory.create_vector_field(num_entities=num_entities_2, num_comp=5)
# Set the scoping ids
field_32.scoping.ids = range(num_entities_2)
# Print the Field
print("5D vector Field : ", '\n',field_32, '\n')
5D vector Field :
DPF Field
Location: Nodal
Unit:
2 entities
Data: 5 components and 0 elementary data
Create a 3d vector Field using the create_3d_vector_field() function
For this approach, the default nature is ‘vector’ and the dimensionality is ‘3D’. Thus, you just
have to use the create_3d_vector_field() function to create a 3D vector |Field|.
# Create the 3d vector Field
field_25 = dpf.fields_factory.create_3d_vector_field(num_entities=num_entities_2)
# Set the scoping ids
field_25.scoping.ids = range(num_entities_2)
# Print the Field
print("Vector Field (3D): ", '\n',field_25, '\n')
Vector Field (3D):
DPF Field
Location: Nodal
Unit:
2 entities
Data: 3 components and 0 elementary data
Create the Field using the field_from_array() function
Different from the other approaches, where you set or append the data after creating the |Field|, here, the data is
used as an input of the field_from_array() function.
This function gets an Numpy array or Python list of either:
1 dimension (one array). In this case, you have to change the |Field|
dimensionalityusing theField.dimensionalitymethod.2 dimensions (one array containing multiple arrays with 3 components). In the is case, you get a 3D vector |Field|.
Note
The |Field| must always assure a homogeneous shape. The shape is a tuple with the number of elementary data and the number of components.
So, for the ‘5D vector |field| we would want a shape of (10,5). Nevertheless, the 2 dimensions data vector we defined (“data_5”) has a elementary data count of 6 (2*3). Thus, we cannot define the ‘5D’ vector |Field| because it would have a (6,5) shape.
Create the ‘3D’ vector Field with an 1 dimensional list.
# Use the field_from_array function
field_23 = dpf.fields_factory.field_from_array(arr=data_3)
# Use the Field.dimensionality method
field_23.dimensionality = dpf.Dimensionality([3])
# Set the scoping ids
field_23.scoping.ids = range(num_entities_2)
# Print the Field
print("3D vector Field: ", '\n',field_23, '\n')
3D vector Field:
DPF Field
Location: Nodal
Unit:
2 entities
Data: 3 components and 2 elementary data
IDs data
------------ ----------
0 4.000000e+00 1.000000e+00 8.000000e+00
1 5.000000e+00 7.000000e+00 9.000000e+00
Create the ‘3D’ vector Field and give a 2 dimensional list.
# Use the field_from_array function
field_24 = dpf.fields_factory.field_from_array(arr=data_5)
# Set the scoping ids
field_24.scoping.ids = range(num_entities_2)
# Print the Field
print("3D vector Field: ", '\n',field_24, '\n')
3D vector Field:
DPF Field
Location: Nodal
Unit:
2 entities
Data: 3 components and 2 elementary data
IDs data
------------ ----------
0 8.000000e+00 4.000000e+00 3.000000e+00
1 3.100000e+01 5.000000e+00 7.000000e+00
You can create a matrix |Field| using the create_matrix_field() function from the fields_factory module.
The default nature here is ‘matrix’. Thus, you only have to define the matrix dimensionality using the
‘num_lines’ and ‘num_col’ arguments.
Create the (2,2) matrix Field.
# Use the create_matrix_field function
field_41 = dpf.fields_factory.create_matrix_field(num_entities=num_entities_3, num_lines=2, num_col=2)
# Set the scoping ids
field_41.scoping.ids = range(num_entities_3)
# Print the Field
print("Matrix Field (2,2) : ", '\n',field_41, '\n')
Matrix Field (2,2) :
DPF Field
Location: Nodal
Unit:
1 entities
Data: 4 components and 0 elementary data
Create the (3,3) matrix Fields.
# Use the create_matrix_field function
field_51 = dpf.fields_factory.create_matrix_field(num_entities=num_entities_3, num_lines=3, num_col=3)
field_52 = dpf.fields_factory.create_matrix_field(num_entities=num_entities_3, num_lines=3, num_col=3)
# Set the scoping ids
field_51.scoping.ids = range(num_entities_3)
field_52.scoping.ids = range(num_entities_3)
# Print the Field
print("Matrix Field 1 (3,3) : ", '\n',field_51, '\n')
print("Matrix Field 2 (3,3) : ", '\n',field_52, '\n')
Matrix Field 1 (3,3) :
DPF Field
Location: Nodal
Unit:
1 entities
Data: 9 components and 0 elementary data
Matrix Field 2 (3,3) :
DPF Field
Location: Nodal
Unit:
1 entities
Data: 9 components and 0 elementary data
Set data to the Fields#
To set a data array to a |Field| use the Field.data method. The |Field| |Scoping| defines how the data is ordered.
For example: the first id in the scoping identifies to which entity the first data entity belongs to.
The data can be in a 1 dimension (one array) or 2 dimensions (one array containing multiple arrays) Numpy array or Python list. When attributed to a |Field|, these data arrays are reshaped to respect the |Field| definition.
Set the data from a 1 dimensional array to the scalar Field.
# Set the data
field_11.data = data_1
# Print the Field
print("Scalar Field : ", '\n',field_11, '\n')
# Print the Fields data
print("Data scalar Field : ", '\n',field_11.data, '\n')
Scalar Field :
DPF Field
Location: Nodal
Unit:
6 entities
Data: 1 components and 6 elementary data
IDs data
------------ ----------
0 6.000000e+00
1 5.000000e+00
2 4.000000e+00
...
Data scalar Field :
[6. 5. 4. 3. 2. 1.]
Set the data from a 2 dimensional array to the scalar Field.
# Set the data
field_12.data = data_2
# Print the Field
print("Scalar Field : ", '\n',field_12, '\n')
# Print the Fields data
print("Data scalar Field : ", '\n',field_12.data, '\n')
Scalar Field :
DPF Field
Location: Nodal
Unit:
6 entities
Data: 1 components and 6 elementary data
IDs data
------------ ----------
0 1.200000e+01
1 7.000000e+00
2 8.000000e+00
...
Data scalar Field :
[12. 7. 8. 9. 31. 1.]
Set the data from a 1 dimensional array to the ‘3D’ vector Field.
# Set the data
field_21.data = data_3
# Print the Field
print("Vector Field : ", '\n',field_21, '\n')
# Print the Fields data
print("Data vector Field: ", '\n',field_21.data, '\n')
Vector Field :
DPF Field
Location: Nodal
Unit:
2 entities
Data: 3 components and 2 elementary data
IDs data
------------ ----------
0 4.000000e+00 1.000000e+00 8.000000e+00
1 5.000000e+00 7.000000e+00 9.000000e+00
Data vector Field:
[[4. 1. 8.]
[5. 7. 9.]]
Set the data from a 1 dimensional array to the ‘5D’ vector Field.
# Set the data
field_31.data = data_4
# Print the Field
print("Vector Field: ", '\n',field_31, '\n')
# Print the Fields data
print("Data vector Field : ", '\n',field_31.data, '\n')
Vector Field:
DPF Field
Location: Nodal
Unit:
2 entities
Data: 5 components and 2 elementary data
IDs data
------------ ----------
0 6.000000e+00 5.000000e+00 4.000000e+00 3.000000e+00 2.000000e+00
1 1.000000e+00 9.000000e+00 7.000000e+00 8.000000e+00 1.000000e+01
Data vector Field :
[[ 6. 5. 4. 3. 2.]
[ 1. 9. 7. 8. 10.]]
Set the data from a 2 dimensional array to the ‘3D’ vector Field.
# Set the data
field_22.data = data_5
# Print the Field
print("Vector Field: ", '\n',field_22, '\n')
# Print the Fields data
print("Data vector Field: ", '\n',field_22.data, '\n')
Vector Field:
DPF Field
Location: Nodal
Unit:
2 entities
Data: 3 components and 2 elementary data
IDs data
------------ ----------
0 8.000000e+00 4.000000e+00 3.000000e+00
1 3.100000e+01 5.000000e+00 7.000000e+00
Data vector Field:
[[ 8. 4. 3.]
[31. 5. 7.]]
Set the data from a 1 dimensional array to the (2,2) matrix Field.
# Set the data
field_41.data = data_6
# Print the Field
print("Matrix Field: ", '\n',field_41, '\n')
# Print the Fields data
print("Data matrix Field: ", '\n',field_41.data, '\n')
Matrix Field:
DPF Field
Location: Nodal
Unit:
1 entities
Data: 4 components and 1 elementary data
IDs data
------------ ----------
0 3.000000e+00 2.000000e+00 1.000000e+00 7.000000e+00
Data matrix Field:
[[3. 2. 1. 7.]]
Set the data from a 1 dimensional array to the (3,3) matrix Field.
# Set the data
field_51.data = data_7
# Print the Field
print("Matrix Field: ", '\n',field_51, '\n')
# Print the Fields data
print("Data matrix Field: ", '\n',field_51.data, '\n')
Matrix Field:
DPF Field
Location: Nodal
Unit:
1 entities
Data: 9 components and 1 elementary data
IDs data
------------ ----------
0 1.500000e+01 3.000000e+00 9.000000e+00 3.100000e+01 1.000000e+00 4.200000e+01 5.000000e+00 6.800000e+01 1.300000e+01
Data matrix Field:
[[15. 3. 9. 31. 1. 42. 5. 68. 13.]]
Set the data from a 2 dimensional array to the (3,3) matrix Field.
# Set the data
field_52.data = data_8
# Print the Field
print("Matrix Field: ", '\n',field_51, '\n')
# Print the Fields data
print("Data matrix Field: ", '\n',field_51.data, '\n')
Matrix Field:
DPF Field
Location: Nodal
Unit:
1 entities
Data: 9 components and 1 elementary data
IDs data
------------ ----------
0 1.500000e+01 3.000000e+00 9.000000e+00 3.100000e+01 1.000000e+00 4.200000e+01 5.000000e+00 6.800000e+01 1.300000e+01
Data matrix Field:
[[15. 3. 9. 31. 1. 42. 5. 68. 13.]]
Append data to the Fields#
You can append a data array to a |Field|, this means adding a new entity with the new data in the |Field|. You have to give the |Scoping| id that this entities will have.
Append data to a scalar |Field|.
# Append the data
field_11.append(scopingid=6, data=data_9)
# Print the Field
print("Scalar Field : ", '\n',field_11, '\n')
# Print the Fields data
print("Data scalar Field: ", '\n',field_11.data, '\n')
Scalar Field :
DPF Field
Location: Nodal
Unit:
7 entities
Data: 1 components and 7 elementary data
IDs data
------------ ----------
0 6.000000e+00
1 5.000000e+00
2 4.000000e+00
...
Data scalar Field:
[ 6. 5. 4. 3. 2. 1. 24.]
Append data to a vector |Field|.
# Append the data
field_21.append(scopingid=2, data=data_10)
# Print the Field
print("Vector Field : ", '\n',field_21, '\n')
# Print the Fields data
print("Data vector Field: ", '\n',field_21.data, '\n')
Vector Field :
DPF Field
Location: Nodal
Unit:
3 entities
Data: 3 components and 3 elementary data
IDs data
------------ ----------
0 4.000000e+00 1.000000e+00 8.000000e+00
1 5.000000e+00 7.000000e+00 9.000000e+00
2 4.700000e+01 3.300000e+01 5.000000e+00
Data vector Field:
[[ 4. 1. 8.]
[ 5. 7. 9.]
[47. 33. 5.]]
Append data to a matrix |Field|.
# Append the data
field_51.append(scopingid=1, data=data_11)
# Print the Field
print("VMatrix Field : ", '\n',field_51, '\n')
# Print the Fields data
print("Data Matrix Field: ", '\n',field_51.data, '\n')
VMatrix Field :
DPF Field
Location: Nodal
Unit:
2 entities
Data: 9 components and 2 elementary data
IDs data
------------ ----------
0 1.500000e+01 3.000000e+00 9.000000e+00 3.100000e+01 1.000000e+00 4.200000e+01 5.000000e+00 6.800000e+01 1.300000e+01
1 8.000000e+00 2.000000e+00 4.000000e+00 6.400000e+01 3.200000e+01 4.700000e+01 1.100000e+01 2.300000e+01 1.000000e+00
Data Matrix Field:
[[15. 3. 9. 31. 1. 42. 5. 68. 13.]
[ 8. 2. 4. 64. 32. 47. 11. 23. 1.]]
Create a |FieldsContainer|#
A |FieldsContainer| is a collection of |Field| ordered by labels. Each |Field| of the |FieldsContainer| has an ID for each label. These ids allow splitting the fields on any criteria.
The most common |FieldsContainer| have the label ‘time’ with ids corresponding to time sets. The label ‘complex’, which is used in a harmonic analysis for example, allows real parts (id=0) to be separated from imaginary parts (id=1).
For more information on DPF data structures, see the DPF data structures tutorials section.
You can create a |FieldsContainer| by:
Create a |FieldsContainer| by an instance of this object#
After defining a |FieldsContainer| by an instance of this object you need to set the labels. Here, we define Fields over time steps labels. So, when you add a |Field| to the |FieldsContainer| you must specify the time step id it belongs to.
# Create the FieldsContainer object
fc_1 = dpf.FieldsContainer()
# Define the labels
fc_1.add_label(label="time")
# Add the Fields
fc_1.add_field(label_space={"time": 0}, field=field_21)
fc_1.add_field(label_space={"time": 1}, field=field_31)
# Print the FieldsContainer
print(fc_1)
DPF Fields Container
with 2 field(s)
defined on labels: time
with:
- field 0 {time: 0} with Nodal location, 3 components and 3 entities.
- field 1 {time: 1} with Nodal location, 5 components and 2 entities.
Create a |FieldsContainer| with the fields_container_factory module#
The fields_container_factory module contains functions that create a |FieldsContainer| with predefined
labels. Here, we use the over_time_freq_fields_container() function that create a |FieldsContainer| with a ‘time’
label.
# Create the FieldsContainer
fc_2 = dpf.fields_container_factory.over_time_freq_fields_container(fields=[field_21, field_31])
# Print the FieldsContainer
print(fc_2)
DPF Fields Container
with 2 field(s)
defined on labels: time
with:
- field 0 {time: 1} with Nodal location, 3 components and 3 entities.
- field 1 {time: 2} with Nodal location, 5 components and 2 entities.