Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add import data tutorials to the main tutorials section #1933

Open
wants to merge 17 commits into
base: doc/new-tutorials-section
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
.. _ref_tutorials_extract_and_explore_results_data:

================================
Extract and explore results data
================================

.. |Field| replace:: :class:`Field<ansys.dpf.core.field.Field>`
.. |Examples| replace:: :mod:`Examples<ansys.dpf.core.examples>`
.. |Result| replace:: :class:`Result <ansys.dpf.core.results.Result>`
.. |FieldsContainer| replace:: :class:`FieldsContainer<ansys.dpf.core.fields_container.FieldsContainer>`
.. |get_entity_data| replace:: :func:`get_entity_data()<ansys.dpf.core.field.Field.get_entity_data>`
.. |get_entity_data_by_id| replace:: :func:`get_entity_data_by_id()<ansys.dpf.core.field.Field.get_entity_data_by_id>`

This tutorial shows how to extract and explore results data from a result file.

When you extract a result from a result file DPF stores it in a |Field|.
This |Field| will contain the data of the result associated with it.

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.

The |Field| data is ordered with respect to its scoping ids (check the :ref:`reft_tutorials_narrow_down_data`
tutorial for more information on scoping manipulations).

Get the results
---------------

Here we will download a result file available in our |Examples| package.
For more information about how to import your result file in DPF check
the :ref:`ref_tutorials_import_result_file` tutorial.

Here we extract the displacement results. The displacement |Result| object gives a |FieldsContainer| when evaluated.
Thus, we will get a |Field| from this |FieldsContainer|.

.. jupyter-execute::

# Import the ``ansys.dpf.core`` module, including examples files and the operators subpackage
from ansys.dpf import core as dpf
from ansys.dpf.core import examples
from ansys.dpf.core import operators as ops

# Define the result file
result_file_path_1 = examples.download_transient_result()

# Create the model
my_model_1 = dpf.Model(data_sources=result_file_path_1)

# Extract the displacement results for the last time step
disp_results = my_model_1.results.displacement.on_last_time_freq.eval()

# Get the displacement field for the last time step
my_disp_field = disp_results[0]

print(my_disp_field)

Extract all data from a field
-----------------------------

You can extract the the entire data in the |Field| as an array (numpy array) or as a list.

Data as an array
^^^^^^^^^^^^^^^^

.. jupyter-execute::

# Get the displacement data as an array
my_data_array = my_disp_field.data
print("Displacement data as an array: ", '\n', my_data_array)

Note that this array is a genuine, local, numpy array (overloaded by the DPFArray):

.. jupyter-execute::

print("Array type: ", type(my_data_array))

Data as a list
^^^^^^^^^^^^^^

.. jupyter-execute::

# Get the displacement data as a list
my_data_list = my_disp_field.data_as_list
print("Displacement data as a list: ", '\n', my_data_list)

Extract specific data from a field
----------------------------------

If you need to access data for specific entities (node, element ...), you can extract it
based on its index (data position on the |Field| by using the |get_entity_data| method), or based
on the entities id (by using the |get_entity_data_by_id| method).

Get the data by the entity index
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. jupyter-execute::

# Get the data from the third entity in the field
data_3_entity = my_disp_field.get_entity_data(index=3)
print("Data entity index=3: ", data_3_entity)

Get the data by the entity ind
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. jupyter-execute::

# Get the data from the entity with id=533
data_533_entity = my_disp_field.get_entity_data_by_id(id=533)
print("Data entity id=533: ", data_533_entity)

Note that the element with id=533 would correspond to an index=2 within the |Field|.

.. jupyter-execute::

# Get the index of the entity with id=533
index_533_entity = my_disp_field.scoping.index(id=533)
print("Index entity id=533: ",index_533_entity)

Be aware that scoping IDs are not sequential. You would get the id of the element in the 533
position of the |Field| with:

.. jupyter-execute::

# Get the id of the entity with index=533
id_533_entity = my_disp_field.scoping.id(index=533)
print("Id entity index=533: ",id_533_entity)


While these methods are acceptable when requesting data for a few elements
or nodes, they should not be used when looping over the entire array. For efficiency,
a |Field|s data can be recovered locally before sending a large number of requests:

.. jupyter-execute::

# Create a deep copy of the field that can be accessed and modified locally.
with my_disp_field.as_local_field() as f:
for i in my_disp_field.scoping.ids[2:50]:
f.get_entity_data_by_id(i)

print(f)
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
.. _ref_tutorials_extract_and_explore_results_metadata:

====================================
Extract and explore results metadata
====================================

.. |Field| replace:: :class:`Field<ansys.dpf.core.field.Field>`
.. |Examples| replace:: :mod:`Examples<ansys.dpf.core.examples>`
.. |ResultInfo| replace:: :class:`ResultInfo<ansys.dpf.core.result_info.ResultInfo>`

You can explore the general results metadata before extracting them by using
the |ResultInfo| object. This metadata includes:

- Analysis type;
- Physics type;
- Number of results;
- Unit system;
- Solver version, date and time;
- Job name;

When you extract a result from a result file DPF stores it in a |Field|.
This |Field| will then contain the metadata for the result associated with it.
This metadata includes:

- Location;
- Scoping;
- Shape of the data stored;
- Number of components;
- Units of the data.

This tutorial shows how to extract and explore results metadata from a result file.

Get the result file
-------------------

Here we will download a result file available in our |Examples| package.
For more information about how to import your result file in DPF check
the :ref:`ref_tutorials_import_result_file` tutorial.

.. jupyter-execute::

# Import the ``ansys.dpf.core`` module, including examples files and the operators subpackage
from ansys.dpf import core as dpf
from ansys.dpf.core import examples
from ansys.dpf.core import operators as ops

# Define the result file
result_file_path_1 = examples.download_transient_result()
# Create the model
my_model_1 = dpf.Model(data_sources=result_file_path_1)

Explore the general results metadata
------------------------------------

Get the |ResultInfo| object from the model and then explore it using this class methods.

.. jupyter-execute::

# Define the ResultInfo object
my_result_info_1 = my_model_1.metadata.result_info

# Get the analysis type
my_analysis_type = my_result_info_1.analysis_type
print("Analysis type: ",my_analysis_type, "\n")

# Get the physics type
my_physics_type = my_result_info_1.physics_type
print("Physics type: ",my_physics_type, "\n")

# Get the number of available results
number_of_results = my_result_info_1.n_results
print("Number of available results: ",number_of_results, "\n")

# Get the unit system
my_unit_system = my_result_info_1.unit_system
print("Unit system: ",my_unit_system, "\n")

# Get the solver version, data and time
my_solver_version = my_result_info_1.solver_version
print("Solver version: ",my_solver_version, "\n")

my_solver_date = my_result_info_1.solver_date
print("Solver date: ", my_solver_date, "\n")

my_solver_time = my_result_info_1.solver_time
print("Solver time: ",my_solver_time, "\n")

# Get the job name
my_job_name = my_result_info_1.job_name
print("Job name: ",my_job_name, "\n")

Explore a given result metadata
-------------------------------

Here we will explore the metadata of the displacement results.

Start by extracting the displacement results:

.. jupyter-execute::

# Extract the displacement results
disp_results = my_model_1.results.displacement.eval()

# Get the displacement field
my_disp_field = disp_results[0]

Explore the displacement results metadata:

.. jupyter-execute::

# Location of the displacement data
my_location = my_disp_field.location
print("Location: ", my_location,'\n')

# Displacement field scoping
my_scoping = my_disp_field.scoping # type and quantity of entities
print("Scoping: ", '\n',my_scoping, '\n')

my_scoping_ids = my_disp_field.scoping.ids # Available entities ids
print("Scoping ids: ", my_scoping_ids, '\n')

# Elementary data count
# Number of entities (how many data vectors we have)
my_elementary_data_count = my_disp_field.elementary_data_count
print("Elementary data count: ", my_elementary_data_count, '\n')

# Components count
# Vectors dimension, here we have a displacement so we expect to have 3 components (X, Y and Z)
my_components_count = my_disp_field.component_count
print("Components count: ", my_components_count, '\n')

# Size
# Length of the data entire vector (equal to the number of elementary data times the number of components)
my_field_size = my_disp_field.size
print("Size: ", my_field_size, '\n')

# Fields shape
# Gives a tuple with the elementary data count and the components count
my_shape = my_disp_field.shape
print("Shape: ", my_shape, '\n')

# Units
my_unit = my_disp_field.unit
print("Unit: ", my_unit, '\n')
Loading
Loading