Skip to content

Commit cbb91ad

Browse files
committed
Merge branch 'master' into bug/raise_error_on_plot_contour_with_empty_mesh
# Conflicts: # tests/test_plotter.py
2 parents 3c89eae + e2ed560 commit cbb91ad

File tree

14 files changed

+123
-29
lines changed

14 files changed

+123
-29
lines changed

.github/workflows/test_docker.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ jobs:
5151
with:
5252
python-version: ${{ matrix.python-version }}
5353

54+
- name: "Setup Graphviz"
55+
uses: ts-graphviz/setup-graphviz@v2
56+
5457
- name: "Install requirements"
5558
run: pip install -r requirements/requirements_build.txt
5659

.github/workflows/tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ jobs:
114114
with:
115115
python-version: ${{ matrix.python-version }}
116116

117+
- name: "Setup Graphviz"
118+
uses: ts-graphviz/setup-graphviz@v2
119+
117120
- name: "Update pip to the latest version and install tox"
118121
shell: pwsh
119122
run: |

requirements/requirements_test.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
ansys-platform-instancemanagement==1.1.2
22
coverage==7.6.11
3+
graphviz==0.20.1
34
imageio==2.36.0
45
imageio-ffmpeg==0.6.0
56
pytest==8.3.4

src/ansys/dpf/core/animator.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def animate_workflow(
6060
save_as="",
6161
mode_number=None,
6262
scale_factor=1.0,
63+
shell_layer=core.shell_layers.top,
6364
**kwargs,
6465
):
6566
unit = loop_over.unit
@@ -121,6 +122,7 @@ def render_frame(frame):
121122
field,
122123
deform_by=deform,
123124
scale_factor_legend=scale_factor[frame],
125+
shell_layer=shell_layer,
124126
**kwargs,
125127
)
126128
kwargs_in = _sort_supported_kwargs(bound_method=self._plotter.add_text, **freq_kwargs)
@@ -267,33 +269,37 @@ def animate(
267269
save_as: str = None,
268270
scale_factor: Union[float, Sequence[float]] = 1.0,
269271
freq_kwargs: dict = None,
272+
shell_layer: core.shell_layers = core.shell_layers.top,
270273
**kwargs,
271274
):
272275
"""
273276
Animate the workflow of the Animator, using inputs.
274277
275278
Parameters
276279
----------
277-
loop_over : Field
280+
loop_over:
278281
Field of values to loop over.
279282
Can for example be a subset of sets of TimeFreqSupport.time_frequencies.
280283
The unit of the Field will be displayed if present.
281-
output_name : str, optional
284+
output_name:
282285
Name of the workflow output to use as Field for each frame's contour.
283286
Defaults to "to_render".
284-
input_name : list of str, optional
287+
input_name:
285288
Name of the workflow inputs to feed loop_over values into.
286289
Defaults to "loop_over".
287-
save_as : str, optional
290+
save_as:
288291
Path of file to save the animation to. Defaults to None. Can be of any format supported
289292
by pyvista.Plotter.write_frame (.gif, .mp4, ...).
290-
scale_factor : float, list, optional
293+
scale_factor:
291294
Scale factor to apply when warping the mesh. Defaults to 1.0. Can be a list to make
292295
scaling frequency-dependent.
293-
freq_kwargs : dict, optional
296+
freq_kwargs:
294297
Dictionary of kwargs given to the :func:`pyvista.Plotter.add_text` method, used to
295298
format the frequency information. Can also contain a "fmt" key,
296299
defining the format for the frequency displayed with a string such as ".3e".
300+
shell_layer:
301+
Enum used to set the shell layer if the field to plot
302+
contains shell elements. Defaults to top layer.
297303
**kwargs : optional
298304
Additional keyword arguments for the animator.
299305
Used by :func:`pyvista.Plotter` (off_screen, cpos, ...),
@@ -314,6 +320,7 @@ def animate(
314320
save_as=save_as,
315321
scale_factor=scale_factor,
316322
freq_kwargs=freq_kwargs,
323+
shell_layer=shell_layer,
317324
**kwargs,
318325
)
319326

src/ansys/dpf/core/collection_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
dpf_vector,
4646
)
4747

48-
if TYPE_CHECKING:
48+
if TYPE_CHECKING: # pragma: no cover
4949
from ansys.dpf.core.support import Support
5050

5151
from ansys.dpf.gate.integral_types import MutableListInt32

src/ansys/dpf/core/data_tree.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import weakref
2929

3030
from ansys.dpf.core import collection_base, common, errors, server as server_module
31-
from ansys.dpf.core.mapping_types import types
31+
from ansys.dpf.core.common import types
3232
from ansys.dpf.gate import (
3333
data_processing_capi,
3434
data_processing_grpcapi,

src/ansys/dpf/core/dpf_operator.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,10 @@
3636
server_meet_version_and_raise,
3737
version_requires,
3838
)
39-
from ansys.dpf.core.common import types_enum_to_types
39+
from ansys.dpf.core.common import types, types_enum_to_types
4040
from ansys.dpf.core.config import Config
4141
from ansys.dpf.core.errors import DpfVersionNotSupported
4242
from ansys.dpf.core.inputs import Inputs
43-
from ansys.dpf.core.mapping_types import types
4443
from ansys.dpf.core.operator_specification import Specification
4544
from ansys.dpf.core.outputs import Output, Outputs, _Outputs
4645
from ansys.dpf.core.unit_system import UnitSystem

src/ansys/dpf/core/fields_container.py

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,17 @@
2626
Contains classes associated with the DPF FieldsContainer.
2727
"""
2828

29+
from __future__ import annotations
30+
31+
from typing import TYPE_CHECKING, Union
32+
2933
from ansys import dpf
3034
from ansys.dpf.core import errors as dpf_errors, field
3135
from ansys.dpf.core.collection_base import CollectionBase
36+
from ansys.dpf.core.common import shell_layers
37+
38+
if TYPE_CHECKING: # pragma: no cover
39+
from ansys.dpf.core import Operator, Result
3240

3341

3442
class FieldsContainer(CollectionBase["field.Field"]):
@@ -543,23 +551,39 @@ def plot(self, label_space: dict = None, **kwargs):
543551
plt.add_field(field=f, **kwargs)
544552
plt.show_figure(**kwargs)
545553

546-
def animate(self, save_as=None, deform_by=None, scale_factor=1.0, **kwargs):
554+
def animate(
555+
self,
556+
save_as: str = None,
557+
deform_by: Union[FieldsContainer, Result, Operator] = None,
558+
scale_factor: Union[float, Sequence[float]] = 1.0,
559+
shell_layer: shell_layers = shell_layers.top,
560+
**kwargs,
561+
):
547562
"""Create an animation based on the Fields contained in the FieldsContainer.
548563
549564
This method creates a movie or a gif based on the time ids of a FieldsContainer.
550565
For kwargs see pyvista.Plotter.open_movie/add_text/show.
551566
552567
Parameters
553568
----------
554-
save_as : Path of file to save the animation to. Defaults to None. Can be of any format
569+
save_as:
570+
Path of file to save the animation to. Defaults to None. Can be of any format
555571
supported by pyvista.Plotter.write_frame (.gif, .mp4, ...).
556-
deform_by : FieldsContainer, Result, Operator, optional
572+
deform_by:
557573
Used to deform the plotted mesh. Must return a FieldsContainer of the same length as
558574
self, containing 3D vector Fields of distances.
559575
Defaults to None, which takes self if possible. Set as False to force static animation.
560576
scale_factor : float, list, optional
561577
Scale factor to apply when warping the mesh. Defaults to 1.0. Can be a list to make
562578
scaling frequency-dependent.
579+
shell_layer:
580+
Enum used to set the shell layer if the field to plot
581+
contains shell elements. Defaults to top layer.
582+
**kwargs:
583+
Additional keyword arguments for the animator.
584+
Used by :func:`pyvista.Plotter` (off_screen, cpos, ...),
585+
or by :func:`pyvista.Plotter.open_movie`
586+
(framerate, quality, ...)
563587
"""
564588
from ansys.dpf.core.animator import Animator
565589

@@ -571,11 +595,17 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, **kwargs):
571595
# Define the field extraction using the fields_container and indices
572596
extract_field_op = dpf.core.operators.utility.extract_field(self)
573597
to_render = extract_field_op.outputs.field
598+
# Add the operators to the workflow
599+
wf.add_operators([extract_field_op, forward_index])
600+
601+
# Treat multi-component fields by taking their norm
574602
n_components = self[0].component_count
575603
if n_components > 1:
576604
norm_op = dpf.core.operators.math.norm(extract_field_op.outputs.field)
605+
wf.add_operator(norm_op)
577606
to_render = norm_op.outputs.field
578607

608+
# Get time steps IDs and values
579609
loop_over = self.get_time_scoping()
580610
frequencies = self.time_freq_support.time_frequencies
581611
if frequencies is None:
@@ -586,8 +616,6 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, **kwargs):
586616

587617
wf.set_input_name("indices", extract_field_op.inputs.indices) # Have to do it this way
588618
wf.connect("indices", forward_index) # Otherwise not accepted
589-
# Add the operators to the workflow
590-
wf.add_operators([extract_field_op, forward_index])
591619

592620
deform = True
593621
# Define whether to deform and what with
@@ -627,6 +655,10 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, **kwargs):
627655
extract_field_op_2.outputs.field, extract_scale_factor_op.outputs.field
628656
)
629657
wf.set_output_name("deform_by", divide_op.outputs.field)
658+
659+
wf.add_operators(
660+
[scale_factor_invert, extract_field_op_2, extract_scale_factor_op, divide_op]
661+
)
630662
else:
631663
scale_factor = None
632664
wf.set_output_name("to_render", to_render)
@@ -647,6 +679,7 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, **kwargs):
647679
loop_over=loop_over_field,
648680
save_as=save_as,
649681
scale_factor=scale_factor,
682+
shell_layer=shell_layer,
650683
**kwargs,
651684
)
652685

src/ansys/dpf/core/mapping_types.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,30 @@
2121
# SOFTWARE.
2222
"""Provides utilities for mapping and transforming data types between Python and C++ representations."""
2323

24+
from enum import Enum # noqa: F401 # pylint: disable=W0611
2425
import inspect
26+
from pathlib import Path # noqa: F401 # pylint: disable=W0611
2527
import sys
2628

27-
from ansys.dpf.core.available_result import * # noqa: F401, F403
29+
# Import types to map to cpp (camel case to snake case)
30+
from ansys.dpf.core.available_result import ( # noqa: F401 # pylint: disable=W0611
31+
AvailableResult,
32+
Homogeneity,
33+
)
34+
from ansys.dpf.core.collection_base import CollectionBase # noqa: F401 # pylint: disable=W0611
2835
from ansys.dpf.core.common import (
2936
_camel_to_snake_case,
3037
_smart_dict_camel,
3138
_snake_to_camel_case,
3239
)
33-
from ansys.dpf.core.data_sources import * # noqa: F401, F403
34-
from ansys.dpf.core.field import * # noqa: F401, F403
35-
from ansys.dpf.core.fields_container import * # noqa: F401, F403
36-
37-
## to do : change that one the module is done
38-
from ansys.dpf.core.meshed_region import * # noqa: F401, F403
39-
from ansys.dpf.core.scoping import * # noqa: F401, F403
40-
from ansys.dpf.core.time_freq_support import * # noqa: F401, F403
40+
from ansys.dpf.core.data_sources import DataSources # noqa: F401 # pylint: disable=W0611
41+
from ansys.dpf.core.dpf_array import DPFArray # noqa: F401 # pylint: disable=W0611
42+
from ansys.dpf.core.field import Field, FieldDefinition # noqa: F401 # pylint: disable=W0611
43+
from ansys.dpf.core.fields_container import FieldsContainer # noqa: F401 # pylint: disable=W0611
44+
from ansys.dpf.core.meshed_region import MeshedRegion # noqa: F401 # pylint: disable=W0611
45+
from ansys.dpf.core.scoping import Scoping # noqa: F401 # pylint: disable=W0611
46+
from ansys.dpf.core.support import Support # noqa: F401 # pylint: disable=W0611
47+
from ansys.dpf.core.time_freq_support import TimeFreqSupport # noqa: F401 # pylint: disable=W0611
4148

4249
map_types_to_cpp = _smart_dict_camel()
4350
for classes in inspect.getmembers(sys.modules[__name__], inspect.isclass):

src/ansys/dpf/core/plotter.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ def add_field(
235235
scale_factor=1.0,
236236
scale_factor_legend=None,
237237
as_linear=True,
238+
shell_layer=eshell_layers.top,
238239
**kwargs,
239240
):
240241
# Get the field name
@@ -277,6 +278,20 @@ def add_field(
277278
mesh_location = meshed_region.elements
278279
else:
279280
raise ValueError("Only elemental, nodal or faces location are supported for plotting.")
281+
282+
# Treat multilayered shells
283+
if not isinstance(shell_layer, eshell_layers):
284+
raise TypeError("shell_layer attribute must be a core.shell_layers instance.")
285+
if field.shell_layers in [
286+
eshell_layers.topbottom,
287+
eshell_layers.topbottommid,
288+
]:
289+
change_shell_layer_op = core.operators.utility.change_shell_layers(
290+
fields_container=field,
291+
e_shell_layer=shell_layer,
292+
)
293+
field = change_shell_layer_op.get_output(0, core.types.field)
294+
280295
component_count = field.component_count
281296
if component_count > 1:
282297
overall_data = np.full((len(mesh_location), component_count), np.nan)
@@ -605,6 +620,7 @@ def add_field(
605620
label_point_size=20,
606621
deform_by=None,
607622
scale_factor=1.0,
623+
shell_layer=eshell_layers.top,
608624
**kwargs,
609625
):
610626
"""Add a field containing data to the plotter.
@@ -629,6 +645,9 @@ def add_field(
629645
Defaults to None.
630646
scale_factor : float, optional
631647
Scaling factor to apply when warping the mesh. Defaults to 1.0.
648+
shell_layer: core.shell_layers, optional
649+
Enum used to set the shell layer if the field to plot
650+
contains shell elements. Defaults to top layer.
632651
**kwargs : optional
633652
Additional keyword arguments for the plotter. More information
634653
are available at :func:`pyvista.plot`.
@@ -655,6 +674,7 @@ def add_field(
655674
deform_by=deform_by,
656675
scale_factor=scale_factor,
657676
as_linear=True,
677+
shell_layer=shell_layer,
658678
**kwargs,
659679
)
660680

0 commit comments

Comments
 (0)