Narrow down data#

MAPDL LS-DYNA FLUENT CFX

This tutorial explains how to scope your results over time and mesh domains.

Download tutorial as Python script Download tutorial as Jupyter notebook

Understanding the scope#

To begin the workflow set up, you need to establish the scoping, that is a spatial and/or temporal subset of the simulation data.

The data in DPF is represented by a |Field|. Thus, narrow down your results means scoping your |Field|. To do so in DPF, you use the |Scoping| object. You can retrieve all the time steps available for a result, but you can also filter them.

Note

Scoping is important because when DPF-Core returns the |Field| object, what Python actually has is a client-side representation of the |Field|, not the entirety of the |Field| itself. This means that all the data of the field is stored within the DPF service. This is important because when building your workflows, the most efficient way of interacting with result data is to minimize the exchange of data between Python and DPF, either by using operators or by accessing exclusively the data that is needed. For more information on the DPF data storage structures see DPF data structures.

In conclusion, the essence of a scoping is to specify a set of time or mesh entities by defining a range of IDs:

../images/drawings/scoping-eg.png

Create a |Scoping| object from scratch#

First, import the necessary PyDPF-Core modules.

# Import the ``ansys.dpf.core`` module
from ansys.dpf import core as dpf

Then, use the available APIs to create a |Scoping| object. It can be created by:

Instanciate a |Scoping|#

Create a time and a mesh |Scoping| by instantiating the |Scoping| object. Use the ‘ids’ and ‘location’ arguments and give the entities ids and location of interest.

A time location in DPF is a |TimeFreqSupport| object. Thus, we chose a ‘time_freq’ location and target a set of time by their ids.

# Define a time list that targets the times ids 14, 15, 16, 17
time_list_1 = [14, 15, 16, 17]

# Create the time Scoping object
time_scoping_1 = dpf.Scoping(ids=time_list_1, location=dpf.locations.time_freq)

Here, we chose a nodal location and target a set of nodes by their ids.

# Define a nodes list that targets the nodes with the ids 103, 204, 334, 1802
nodes_ids_1 = [103, 204, 334, 1802]

#  Create the mesh Scoping object
mesh_scoping_1 = dpf.Scoping(ids=nodes_ids_1, location=dpf.locations.nodal)

Use the scoping factory module#

Create a |Scoping| object by using the time_freq_scoping_factory module for a temporal |Scoping| and the mesh_scoping_factory module for a spatial |Scoping|.

Here, we use the scoping_by_sets() function so we can have different time steps in the |Scoping|. This function gives a |Scoping| on a ‘time_freq’ location.

# Define a time list that targets the times ids 14, 15, 16, 17
time_list_2 = [14, 15, 16, 17]

# Create the time Scoping object
time_scoping_2 = dpf.time_freq_scoping_factory.scoping_by_sets(cumulative_sets=time_list_2)

Here, we use the nodal_scoping() function so we have a mesh |Scoping| in a nodal location.

# Define a nodes list that targets the nodes with the ids 103, 204, 334, 1802
nodes_ids_2 = [103, 204, 334, 1802]

# Create the mesh Scoping object
mesh_scoping_2 = dpf.mesh_scoping_factory.nodal_scoping(node_ids=nodes_ids_2)

Extract a |Scoping|#

You can extract |Scoping| from some DPF objects. They are:

Define the objects#

First, import a result file and create a |Model|. For this tutorial, you can use one available in the |Examples| module. For more information about how to import your own result file in DPF, see the Import a result file in DPF tutorial.

# Import the examples module
from ansys.dpf.core import examples
# Import the operators module
from ansys.dpf.core import operators as ops

# Define the result file path
result_file_path_1 = examples.download_transient_result()
# Create the DataSources object
ds_1 = dpf.DataSources(result_path=result_file_path_1)
# Create the model
model_1 = dpf.Model(data_sources=ds_1)

From this result file we extract:

# Get the MeshedRegion
meshed_region_1 = model_1.metadata.meshed_region

# Get a FieldsContainer with the displacement results
disp_fc = model_1.results.displacement.on_all_time_freqs.eval()

# Get a Field from the FieldsContainer
disp_field = disp_fc[0]

Extract the time |Scoping|#

Extract the time |Scoping| is extracting the scoping of the time frequencies from the |TimeFreqSupport| of the DPF object.

You can extract the |TimeFreqSupport| available for the results by accessing the |Model| Metadata. Thus, you must use the Model.metadata method. From the Metadata, you can get the |TimeFreqSupport| by using the Metadata.time_freq_support method.

# Extract the TimeFreq support
tfs_1 = model_1.metadata.time_freq_support

To extract the time frequencies you use the TimeFreqSupport.time_frequencies method. The time frequencies are given in a Field. Thus, to get the time |Scoping| you need to use the Field.scoping method. For this approach, the time frequencies are given in a ‘TimeFreq_sets’ location.

# Extract the time frequencies
t_freqs_1 = tfs_1.time_frequencies

# Extract the time scoping
time_scop_1 = t_freqs_1.scoping

#Print the time scoping
print(time_scop_1)
DPF  Scoping: 
  with TimeFreq_steps location and 1 entity

You can extract the |TimeFreqSupport| of each |Field| in the |FieldsContainer| by using the FieldsContainer.time_freq_support method.

# Extract the TimeFreq support
tfs_2 = disp_fc.time_freq_support

To extract the time frequencies you use the TimeFreqSupport.time_frequencies method. The time frequencies are given in a Field. Thus, to get the time |Scoping| you need to use the Field.scoping method.

# Extract the time frequencies
t_freqs_2 = tfs_2.time_frequencies

# Extract the time scoping
time_scop_2 = t_freqs_2.scoping

#Print the time scoping
print(time_scop_2)
DPF  Scoping: 
  with TimeFreq_steps location and 1 entity

You can extract the |TimeFreqSupport| of a |Field| by using the Field.time_freq_support method.

# Extract the TimeFreq support
tfs_3 = disp_field.time_freq_support

To extract the time frequencies you use the TimeFreqSupport.time_frequencies method. The time frequencies are given in a Field. Thus, to get the time |Scoping| you need to use the Field.scoping method.

# Extract the time frequencies
t_freqs_3 = tfs_1.time_frequencies

# Extract the time scoping
time_scop_3 = t_freqs_3.scoping

#Print the time scoping
print(time_scop_3)
DPF  Scoping: 
  with TimeFreq_steps location and 1 entity

Extract the mesh |Scoping|#

You can extract the mesh |Scoping| from a |MeshedRegion| using:

Use the from_mesh operator

Extract the mesh |Scoping| from the |MeshedRegion| using the from_mesh operator. It gets the |Scoping| for the entire mesh with a ‘nodal’ location. You can also get an ‘elemental’ location by using the ‘requested_location’ argument.

# Extract the mesh scoping
mesh_scoping_3 = ops.scoping.from_mesh(mesh=meshed_region_1).eval()

# Print the mesh Scoping
print("Scoping from mesh", "\n", mesh_scoping_3, "\n")
Scoping from mesh 
 DPF  Scoping: 
  with Nodal location and 3820 entities
 

Use the Elements object

You can obtain the |Elements| object from a given |MeshedRegion| by using the MeshedRegion.elements method. You can extract the mesh |Scoping| from the |Elements| object by using the Elements.scoping method. It gets the |Scoping| for the entire mesh with a ‘elemental’ location.

# Extract the mesh scoping
mesh_scoping_4 = meshed_region_1.elements.scoping

# Print the mesh Scoping
print("Scoping from mesh", "\n", mesh_scoping_4, "\n")
Scoping from mesh 
 DPF  Scoping: 
  with Elemental location and 789 entities
 

Use the Nodes object

You can obtain the |Nodes| object from a given |MeshedRegion| by using the MeshedRegion.nodes method. You can extract the mesh |Scoping| from the |Nodes| object by using the Nodes.scoping method. It gets the |Scoping| for the entire mesh with a ‘nodal’ location.

# Extract the mesh scoping
mesh_scoping_5 = meshed_region_1.nodes.scoping

# Print the mesh Scoping
print("Scoping from mesh", "\n", mesh_scoping_5, "\n")
Scoping from mesh 
 DPF  Scoping: 
  with Nodal location and 3820 entities
 

Extract the mesh Scoping from the |FieldsContainer| using the extract_scoping operator. This operator gets the mesh |Scoping| for each |Field| in the |FieldsContainer|. Thus, you must specify the output as a |ScopingsContainer|.

# Define the extract_scoping operator
extract_scop_fc_op = ops.utility.extract_scoping(field_or_fields_container=disp_fc)

# Get the mesh Scopings from the operators output
mesh_scoping_6 = extract_scop_fc_op.outputs.mesh_scoping_as_scopings_container()

# Print the mesh Scopings
print("Scoping from FieldsContainer", "\n", mesh_scoping_6, "\n")
Scoping from FieldsContainer 
 DPF  Scopings Container
  with 35 scoping(s)
  defined on labels: time 

  with:
  - scoping 0 {time:  1, } located on Nodal 3820 entities.
  - scoping 1 {time:  2, } located on Nodal 3820 entities.
  - scoping 2 {time:  3, } located on Nodal 3820 entities.
  - scoping 3 {time:  4, } located on Nodal 3820 entities.
  - scoping 4 {time:  5, } located on Nodal 3820 entities.
  - scoping 5 {time:  6, } located on Nodal 3820 entities.
  - scoping 6 {time:  7, } located on Nodal 3820 entities.
  - scoping 7 {time:  8, } located on Nodal 3820 entities.
  - scoping 8 {time:  9, } located on Nodal 3820 entities.
  - scoping 9 {time:  10, } located on Nodal 3820 entities.
  - scoping 10 {time:  11, } located on Nodal 3820 entities.
  - scoping 11 {time:  12, } located on Nodal 3820 entities.
  - scoping 12 {time:  13, } located on Nodal 3820 entities.
  - scoping 13 {time:  14, } located on Nodal 3820 entities.
  - scoping 14 {time:  15, } located on Nodal 3820 entities.
  - scoping 15 {time:  16, } located on Nodal 3820 entities.
  - scoping 16 {time:  17, } located on Nodal 3820 entities.
  - scoping 17 {time:  18, } located on Nodal 3820 entities.
  - scoping 18 {time:  19, } located on Nodal 3820 entities.
  - scoping 19 {time:  20, } located on Nodal 3820 entities.
  - scoping 20 {time:  21, } located on Nodal 3820 entities.
  - scoping 21 {time:  22, } located on Nodal 3820 entities.
  - scoping 22 {time:  23, } located on Nodal 3820 entities.
  - scoping 23 {time:  24, } located on Nodal 3820 entities.
  - scoping 24 {time:  25, } located on Nodal 3820 entities.
  - scoping 25 {time:  26, } located on Nodal 3820 entities.
  - scoping 26 {time:  27, } located on Nodal 3820 entities.
  - scoping 27 {time:  28, } located on Nodal 3820 entities.
  - scoping 28 {time:  29, } located on Nodal 3820 entities.
  - scoping 29 {time:  30, } located on Nodal 3820 entities.
  - scoping 30 {time:  31, } located on Nodal 3820 entities.
  - scoping 31 {time:  32, } located on Nodal 3820 entities.
  - scoping 32 {time:  33, } located on Nodal 3820 entities.
  - scoping 33 {time:  34, } located on Nodal 3820 entities.
  - scoping 34 {time:  35, } located on Nodal 3820 entities.
 

You can extract the mesh |Scoping| from a |Field| using:

Use the extract_scoping operator

This operator gets the mesh |Scoping| from the result |Field|. This means it gets the |Scoping| where the result is defined at.

# Extract the mesh scoping
mesh_scoping_7 = ops.utility.extract_scoping(field_or_fields_container=disp_field).eval()

# Print the mesh Scoping
print("Scoping from Field ", "\n", mesh_scoping_7, "\n")
Scoping from Field  
 DPF  Scoping: 
  with Nodal location and 3820 entities
 

Use the Field.scoping method

This method gets the mesh |Scoping| from the result |Field|. This means it gets the |Scoping| where the result is defined at.

# Extract the mesh scoping
mesh_scoping_8 = disp_field

# Print the mesh Scoping
print("Scoping from Field", "\n", mesh_scoping_8, "\n")
Scoping from Field 
 DPF displacement_0.s Field
  Location: Nodal
  Unit: m
  3820 entities 
  Data: 3 components and 3820 elementary data 

  Nodal
  IDs                   data(m)
  ------------          ----------
  525                   0.000000e+00   0.000000e+00   0.000000e+00   
                        
  534                   0.000000e+00   0.000000e+00   0.000000e+00   
                        
  533                   0.000000e+00   0.000000e+00   0.000000e+00   
                        
  ...

 

Use a |Scoping|#

The |Scoping| object can be used :

Extract and scope the results#

You can extract and scope a result using the Model.results method or the result operator inputs. Those two approaches handle |Result| objects. Thus, to scope the results when extracting them you use the ‘time_scoping’ and ‘mesh_scoping’ arguments and give the Scopings of interest.

Here, we extract and scope the displacement results.

# Extract and scope the result using the Model.results method
disp_model = model_1.results.displacement(time_scoping=time_scoping_1, mesh_scoping=mesh_scoping_1).eval()

# Extract and scope the results using the result.displacement operator
disp_op = ops.result.displacement(data_sources=ds_1, time_scoping=time_scoping_1, mesh_scoping=mesh_scoping_1).eval()

# Print the displacement results
print("Displacement from Model.results ", "\n", disp_model, "\n")
print("Displacement from result.displacement operator", "\n", disp_op, "\n")
Displacement from Model.results  
 DPF displacement(s)Fields Container
  with 4 field(s)
  defined on labels: time 

  with:
  - field 0 {time:  14} with Nodal location, 3 components and 4 entities.
  - field 1 {time:  15} with Nodal location, 3 components and 4 entities.
  - field 2 {time:  16} with Nodal location, 3 components and 4 entities.
  - field 3 {time:  17} with Nodal location, 3 components and 4 entities.
 

Displacement from result.displacement operator 
 DPF displacement(s)Fields Container
  with 4 field(s)
  defined on labels: time 

  with:
  - field 0 {time:  14} with Nodal location, 3 components and 4 entities.
  - field 1 {time:  15} with Nodal location, 3 components and 4 entities.
  - field 2 {time:  16} with Nodal location, 3 components and 4 entities.
  - field 3 {time:  17} with Nodal location, 3 components and 4 entities.
 

Extract and rescope the results#

The mesh |Scoping| can be changed after the result extraction or manipulation by using the rescope operator. It takes a |Field| or |FieldsContainer| that contains the results data and rescope them.

Here, we rescope the displacement results.

# Extract the results for the entire mesh
disp_all_mesh = model_1.results.displacement.eval()

# Rescope the displacement results to get the data only for a specific set of nodes
disp_rescope = ops.scoping.rescope(fields=disp_all_mesh, mesh_scoping=mesh_scoping_1).eval()

# Print the displacement results for the entire mesh
print("Displacement results for the entire mesh", "\n", disp_all_mesh, "\n")

# Print the displacement results for the specific set of nodes
print("Displacement results rescoped ", "\n", disp_rescope, "\n")
Displacement results for the entire mesh 
 DPF displacement(s)Fields Container
  with 1 field(s)
  defined on labels: time 

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

Displacement results rescoped  
 DPF displacement(s)Fields Container
  with 1 field(s)
  defined on labels: time 

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