Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
13 changes: 13 additions & 0 deletions src/ansys/dpf/core/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@
``fields_container[index]``.
"""

_EMPTY_MESH_PLOTTING_MSG = """"
The mesh support is empty.
Either provide one to the plot function called, or use MeshedRegion.plot
and provide the current data as parameter.
"""


class DpfValueError(ValueError):
"""Error raised when a specific DPF error value must be defined."""
Expand Down Expand Up @@ -80,6 +86,13 @@ def __init__(self, msg=_FIELD_CONTAINER_PLOTTING_MSG):
ValueError.__init__(self, msg)


class EmptyMeshPlottingError(ValueError):
"""Error raised when attempting to plot data with no mesh."""

def __init__(self, msg=_EMPTY_MESH_PLOTTING_MSG):
ValueError.__init__(self, msg)


class InvalidANSYSVersionError(RuntimeError):
"""Error raised when the Ansys version is invalid."""

Expand Down
43 changes: 33 additions & 10 deletions src/ansys/dpf/core/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,21 @@

"""Field."""

from __future__ import annotations

from typing import TYPE_CHECKING

import numpy as np

from ansys import dpf
from ansys.dpf.core import dimensionality, errors, meshed_region, scoping, time_freq_support
from ansys.dpf.core.common import _get_size_of_list, locations, natures, types
from ansys.dpf.core.common import (
_get_size_of_list,
locations,
natures,
shell_layers as eshell_layers,
types,
)
from ansys.dpf.core.field_base import _FieldBase, _LocalFieldBase
from ansys.dpf.core.field_definition import FieldDefinition
from ansys.dpf.gate import (
Expand All @@ -37,6 +47,11 @@
field_grpcapi,
)

if TYPE_CHECKING:
from ansys.dpf.core.dpf_operator import Operator
from ansys.dpf.core.meshed_region import MeshedRegion
from ansys.dpf.core.results import Result


class Field(_FieldBase):
"""Represents the main simulation data container.
Expand Down Expand Up @@ -500,7 +515,14 @@ def to_nodal(self):
op.inputs.connect(self)
return op.outputs.field()

def plot(self, shell_layers=None, deform_by=None, scale_factor=1.0, **kwargs):
def plot(
self,
shell_layers: eshell_layers = None,
deform_by: Union[Field, Result, Operator] = None,
scale_factor: float = 1.0,
meshed_region: MeshedRegion = None,
**kwargs,
):
"""Plot the field or fields container on the mesh support if it exists.

Warning
Expand All @@ -522,21 +544,22 @@ def plot(self, shell_layers=None, deform_by=None, scale_factor=1.0, **kwargs):

Parameters
----------
shell_layers : shell_layers, optional
shell_layers:
Enum used to set the shell layers if the model to plot
contains shell elements. The default is ``None``.
deform_by : Field, Result, Operator, optional
contains shell elements. Defaults to the top layer.
deform_by:
Used to deform the plotted mesh. Must output a 3D vector field.
Defaults to None.
scale_factor : float, optional
Scaling factor to apply when warping the mesh. Defaults to 1.0.
**kwargs : optional
scale_factor:
Scaling factor to apply when warping the mesh.
**kwargs:
Additional keyword arguments for the plotter. For additional keyword
arguments, see ``help(pyvista.plot)``.
"""
from ansys.dpf.core.plotter import Plotter

pl = Plotter(self.meshed_region, **kwargs)
if meshed_region is None:
meshed_region = self.meshed_region
pl = Plotter(meshed_region, **kwargs)
return pl.plot_contour(
self,
shell_layers,
Expand Down
31 changes: 17 additions & 14 deletions src/ansys/dpf/core/plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
from ansys.dpf.core.nodes import Node, Nodes

if TYPE_CHECKING: # pragma: no cover
from ansys.dpf.core import Operator, Result
from ansys.dpf.core.fields_container import FieldsContainer
from ansys.dpf.core.meshed_region import MeshedRegion


Expand Down Expand Up @@ -831,31 +833,30 @@ def plot_chart(fields_container, off_screen=False, screenshot=None):

def plot_contour(
self,
field_or_fields_container,
shell_layers=None,
meshed_region=None,
deform_by=None,
scale_factor=1.0,
field_or_fields_container: Union[Field, FieldsContainer],
shell_layers: eshell_layers = None,
meshed_region: MeshedRegion = None,
deform_by: Union[Field, Result, Operator] = None,
scale_factor: float = 1.0,
**kwargs,
):
"""Plot the contour result on its mesh support.

You cannot plot a fields container containing results at several
time steps.
time steps. Use :func:`FieldsContainer.animate` instead.

Parameters
----------
field_or_fields_container : dpf.core.Field or dpf.core.FieldsContainer
field_or_fields_container:
Field or field container that contains the result to plot.
shell_layers : core.shell_layers, optional
shell_layers:
Enum used to set the shell layers if the model to plot
contains shell elements.
deform_by : Field, Result, Operator, optional
contains shell elements. Defaults to the top layer.
deform_by:
Used to deform the plotted mesh. Must output a 3D vector field.
Defaults to None.
scale_factor : float, optional
Scaling factor to apply when warping the mesh. Defaults to 1.0.
**kwargs : optional
scale_factor:
Scaling factor to apply when warping the mesh.
**kwargs:
Additional keyword arguments for the plotter. For more information,
see ``help(pyvista.plot)``.
"""
Expand Down Expand Up @@ -892,6 +893,8 @@ def plot_contour(
mesh = meshed_region
else:
mesh = self._mesh
if mesh.elements.n_elements == 0 and mesh.nodes.n_nodes == 0 and mesh.faces.n_faces == 0:
raise dpf_errors.EmptyMeshPlottingError

# get mesh scoping
location = None
Expand Down
10 changes: 10 additions & 0 deletions tests/test_plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,16 @@ def test_field_shell_plot_scoping_elemental(multishells):
f.plot(shell_layers=core.shell_layers.top)


@pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista")
def test_field_plot_raise_empty_mesh(simple_bar):
ds = core.DataSources(simple_bar)
stream_prov = core.operators.metadata.streams_provider(data_sources=ds)
result_op = core.operators.result.displacement(streams_container=stream_prov)
field = result_op.outputs.fields_container()[0]
with pytest.raises(dpf_errors.EmptyMeshPlottingError):
field.plot()


@pytest.mark.skipif(not HAS_PYVISTA, reason="Please install pyvista")
def test_throw_shell_layers(multishells):
model = core.Model(multishells)
Expand Down
Loading