Skip to content

Commit feb6025

Browse files
authored
add new examples to expose fields containers capabilities (#123)
1 parent 3d773c9 commit feb6025

File tree

4 files changed

+251
-5
lines changed

4 files changed

+251
-5
lines changed

ansys/dpf/core/mesh_scoping_factory.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"""
77

88
from ansys.dpf.core import Scoping
9-
from ansys.dpf.core import errors as dpf_errors
109
from ansys.dpf.core.common import locations
1110

1211

@@ -26,8 +25,6 @@ def nodal_scoping(node_ids, server=None):
2625
-------
2726
scoping : ansys.dpf.core.Scoping
2827
"""
29-
if not isinstance(node_ids, list):
30-
raise dpf_errors.InvalidTypeError("list", "node_ids")
3128
scoping = Scoping(server=server, ids=node_ids, location=locations.nodal)
3229
return scoping
3330

@@ -48,8 +45,6 @@ def elemental_scoping(element_ids, server=None):
4845
-------
4946
scoping : ansys.dpf.core.Scoping
5047
"""
51-
if not isinstance(element_ids, list):
52-
raise dpf_errors.InvalidTypeError("list", "element_ids")
5348
scoping = Scoping(server=server, ids=element_ids, location=locations.elemental)
5449
return scoping
5550

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"""
2+
.. _ref_results_over_time:
3+
4+
Scope results over custom time domains
5+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6+
The ``Result`` class, which are instances created by the ``Model``, give
7+
access to helpers for requesting results on specific mesh and time scopings.
8+
With these helpers, working on a temporal subset of the
9+
model is straightforward. In this example, different ways to choose the temporal subset to
10+
evaluate a result are exposed. This example can be extended to frequency subsets.
11+
12+
Import necessary modules:
13+
"""
14+
15+
from ansys.dpf import core as dpf
16+
from ansys.dpf.core import examples
17+
18+
19+
###############################################################################
20+
# Create a model object to establish a connection with an example result file:
21+
model = dpf.Model(examples.download_transient_result())
22+
print(model)
23+
24+
25+
###############################################################################
26+
# Request specific time sets
27+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~
28+
# If specific time sets are of interest, looking into the ``TimeFreqSupport``
29+
# and connect a given ``time_scoping`` accordingly to the cumulative indexes can be useful.
30+
31+
print(model.metadata.time_freq_support)
32+
33+
time_sets = [1, 3, 10]
34+
disp = model.results.displacement.on_time_scoping(time_sets).eval()
35+
36+
print(disp)
37+
38+
# Or using a scoping
39+
time_sets_scoping = dpf.time_freq_scoping_factory.scoping_by_sets([1, 3, 10])
40+
disp = model.results.displacement.on_time_scoping(time_sets_scoping).eval()
41+
42+
print(disp)
43+
44+
###############################################################################
45+
# Equivalent to:
46+
disp_op = model.results.displacement()
47+
disp_op.inputs.time_scoping(time_sets)
48+
disp = disp_op.outputs.fields_container()
49+
50+
51+
###############################################################################
52+
# Equivalent to:
53+
disp = model.results.displacement(time_scoping=time_sets_scoping).eval()
54+
55+
###############################################################################
56+
# Request specific time steps
57+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~
58+
# If specific time steps or load steps are of interest, looking into the
59+
# ``TimeFreqSupport`` and connect a given ``time_scoping`` located on steps can be done.
60+
time_steps_scoping = dpf.time_freq_scoping_factory.scoping_by_load_step([1])
61+
disp = model.results.displacement.on_time_scoping(time_steps_scoping).eval()
62+
63+
print(disp)
64+
65+
###############################################################################
66+
# Equivalent to:
67+
disp_op = model.results.displacement()
68+
disp_op.inputs.time_scoping(time_steps_scoping)
69+
disp = disp_op.outputs.fields_container()
70+
71+
###############################################################################
72+
# Using helpers
73+
# ~~~~~~~~~~~~~
74+
# Evaluate at all times.
75+
76+
disp = model.results.displacement.on_all_time_freqs().eval()
77+
78+
###############################################################################
79+
# Evaluate at first and last times
80+
disp = model.results.displacement.on_first_time_freq().eval()
81+
print(disp)
82+
disp = model.results.displacement.on_last_time_freq().eval()
83+
print(disp)
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
"""
2+
.. _ref_results_over_space:
3+
4+
Scope results over custom space domains
5+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6+
The ``Result`` class, which are instances created by the ``Model``, give
7+
access to helpers for requesting results on specific mesh and time scopings.
8+
With these helpers, working on a spatial subset of the model is straightforward.
9+
In this example, different ways to choose the spatial subset to
10+
evaluate a result are exposed
11+
12+
Import necessary modules:
13+
"""
14+
15+
from ansys.dpf import core as dpf
16+
from ansys.dpf.core import examples
17+
18+
###############################################################################
19+
# Create a model object to establish a connection with an example result file:
20+
model = dpf.Model(examples.download_all_kinds_of_complexity())
21+
print(model)
22+
23+
###############################################################################
24+
# Choose specific nodes
25+
# ~~~~~~~~~~~~~~~~~~~~~
26+
# If some nodes or elements are specifically of interest, a nodal ``mesh_scoping``
27+
# can be connected.
28+
29+
nodes_scoping = dpf.mesh_scoping_factory.nodal_scoping(range(400, 500))
30+
print(nodes_scoping)
31+
32+
###############################################################################
33+
# or
34+
nodes_scoping = dpf.Scoping(ids=range(400, 500), location=dpf.locations.nodal)
35+
print(nodes_scoping)
36+
37+
###############################################################################
38+
39+
disp = model.results.displacement.on_mesh_scoping(nodes_scoping).eval()
40+
41+
model.metadata.meshed_region.plot(disp)
42+
43+
###############################################################################
44+
# Equivalent to:
45+
disp_op = model.results.displacement()
46+
disp_op.inputs.mesh_scoping(nodes_scoping)
47+
disp = disp_op.outputs.fields_container()
48+
49+
###############################################################################
50+
# Equivalent to:
51+
disp = model.results.displacement(mesh_scoping=nodes_scoping).eval()
52+
53+
###############################################################################
54+
# Choose specific elements
55+
# ~~~~~~~~~~~~~~~~~~~~~~~~
56+
# If some elements are specifically of interest, an elemental ``mesh_scoping``
57+
# can be connected.
58+
59+
elements_scoping = dpf.mesh_scoping_factory.elemental_scoping(range(500, 5000))
60+
print(elements_scoping)
61+
62+
# or
63+
elements_scoping = dpf.Scoping(ids=range(500, 5000), location=dpf.locations.elemental)
64+
print(elements_scoping)
65+
66+
volume = model.results.elemental_volume.on_mesh_scoping(elements_scoping).eval()
67+
68+
model.metadata.meshed_region.plot(volume)
69+
70+
###############################################################################
71+
# Equivalent to:
72+
volume_op = model.results.elemental_volume()
73+
volume_op.inputs.mesh_scoping(elements_scoping)
74+
volume = volume_op.outputs.fields_container()
75+
76+
###############################################################################
77+
# Equivalent to:
78+
volume = model.results.elemental_volume(mesh_scoping=elements_scoping).eval()
79+
80+
###############################################################################
81+
# Choose specific named selections
82+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83+
# Named selections (also known as components) can be selected to create
84+
# a spatial domain for a result. A ``mesh_scoping`` can be created with a
85+
# named selection.
86+
# To know the available named selections in the result file, use:
87+
88+
print(model.metadata.available_named_selections)
89+
90+
###############################################################################
91+
# Get the ``mesh_scoping`` of a named selection:
92+
93+
mesh_scoping = model.metadata.named_selection('_CM82')
94+
print(mesh_scoping)
95+
96+
###############################################################################
97+
# Connect this ``mesh_scoping`` to the result provider
98+
volume = model.results.elemental_volume(mesh_scoping=mesh_scoping).eval()
99+
model.metadata.meshed_region.plot(volume)
100+
101+
###############################################################################
102+
# Equivalent to:
103+
volume = model.results.elemental_volume.on_named_selection('_CM82')
104+
105+
###############################################################################
106+
# Equivalent to:
107+
ns_provider = dpf.operators.scoping.on_named_selection(
108+
requested_location=dpf.locations.elemental,
109+
named_selection_name='_CM82',
110+
data_sources=model,
111+
)
112+
volume = model.results.elemental_volume(mesh_scoping=ns_provider).eval()
113+
114+
###############################################################################
115+
# Split results depending on spatial properties
116+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
117+
# For many applications, it can be useful to request results on different subsets
118+
# of the model. The ``ScopingsContainer`` entity contains different ``Scopings``
119+
# and can be connected to any result provider to get results split with the
120+
# same partition as the input ``ScopingsContainer``.
121+
# For example, some application require to get results split by body, by material,
122+
# by element types. It might also be necessary to get results by element shape types
123+
# (shell, solid, beam) to average data properly...
124+
# Customers might also require split by entirely custom spatial domains.
125+
126+
127+
###############################################################################
128+
# Split results by element shapes
129+
stress = model.results.stress.split_by_shape.on_location(dpf.locations.nodal).eval()
130+
print(stress)
131+
132+
shell_stresses = stress.shell_fields()
133+
model.metadata.meshed_region.plot(shell_stresses[0])
134+
135+
solid_stresses = stress.solid_fields()
136+
model.metadata.meshed_region.plot(solid_stresses[0])
137+
138+
###############################################################################
139+
# Split results by bodies
140+
stress = model.results.stress.split_by_body.on_location(dpf.locations.nodal).eval()
141+
print(stress)
142+
143+
for body_id in stress.get_mat_scoping().ids:
144+
field = stress.get_field_by_mat_id(body_id)
145+
if field.elementary_data_count > 0:
146+
model.metadata.meshed_region.plot(field)
147+
148+
###############################################################################
149+
# Create a custom spatial split
150+
scopings_container = dpf.ScopingsContainer()
151+
scopings_container.add_label("custom_split")
152+
scopings_container.add_scoping(
153+
{"custom_split": 1},
154+
dpf.Scoping(ids=range(100, 500), location=dpf.locations.elemental),
155+
)
156+
scopings_container.add_scoping(
157+
{"custom_split": 2},
158+
dpf.Scoping(ids=range(500, 5000), location=dpf.locations.elemental),
159+
)
160+
161+
###############################################################################
162+
elemental_stress = model.results.stress.on_location(dpf.locations.elemental)(
163+
mesh_scoping=scopings_container)\
164+
.eval()
165+
print(elemental_stress)
166+
167+
for field in elemental_stress:
168+
model.metadata.meshed_region.plot(field)

0 commit comments

Comments
 (0)