Beispiel #1
0
    def add_mesh(self, meshed_region, **kwargs):
        try:
            import pyvista as pv
        except ModuleNotFoundError:
            raise ModuleNotFoundError(
                "To use plotting capabilities, please install pyvista "
                "with :\n pip install pyvista>=0.24.0")
        pv_version = pv.__version__
        version_to_reach = '0.30.0'  # when stitle started to be deprecated
        meet_ver = meets_version(pv_version, version_to_reach)
        if meet_ver:
            # use scalar_bar_args
            scalar_bar_args = {'title': 'Mesh'}
            kwargs.setdefault("scalar_bar_args", scalar_bar_args)
        else:
            # use stitle
            has_attribute_scalar_bar = False
            try:
                has_attribute_scalar_bar = hasattr(self._plotter, 'scalar_bar')
            except:
                has_attribute_scalar_bar = False

            if not has_attribute_scalar_bar:
                kwargs.setdefault("stitle", "Mesh")
            else:
                if self._plotter.scalar_bar.GetTitle() is None:
                    kwargs.setdefault("stitle", "Mesh")
        kwargs.setdefault("show_edges", True)
        kwargs.setdefault("nan_color", "grey")

        kwargs_in = self._sort_supported_kwargs(
            bound_method=self._plotter.add_mesh, **kwargs)
        self._plotter.add_mesh(meshed_region.grid, **kwargs_in)
Beispiel #2
0
import numpy as np
import pytest

import ansys.dpf.core.operators as op
import conftest
from ansys import dpf
from ansys.dpf.core.check_version import meets_version, get_server_version

SERVER_VERSION_HIGHER_THAN_3_0 = meets_version(get_server_version(dpf.core._global_server()), "3.0")


def test_create_workflow():
    wf = dpf.core.Workflow()
    assert wf._message.id


def test_connect_field_workflow():
    wf = dpf.core.Workflow()
    op = dpf.core.Operator("min_max")
    inpt = dpf.core.Field(nentities=3)
    data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    scop = dpf.core.Scoping()
    scop.ids = [1, 2, 3]
    inpt.data = data
    inpt.scoping = scop

    wf.add_operator(op)
    wf.set_input_name("field", op, 0)
    wf.set_output_name("min", op, 0)
    wf.set_output_name("max", op, 1)
    wf.connect("field", inpt)
Beispiel #3
0
def test_meets_version():
    # first is server version, second is version to meet
    assert check_version.meets_version("1.32.0", "1.31.0")
    assert check_version.meets_version("1.32.1", "1.32.0")
    assert check_version.meets_version("1.32.0", "1.32.0")
    assert check_version.meets_version("1.32", "1.32")
    assert check_version.meets_version("1.32", "1.31")
    assert check_version.meets_version("1.32", "1.31.0")
    assert check_version.meets_version("1.32.0", "1.31")
    assert check_version.meets_version("1.32.0", "1.31.1")
    assert not check_version.meets_version("1.31.0", "1.32")
    assert not check_version.meets_version("1.31.0", "1.32.0")
    assert not check_version.meets_version("1.31.1", "1.32")
    assert not check_version.meets_version("1.31.1", "1.32.1")
    assert not check_version.meets_version("1.31", "1.32")
    assert not check_version.meets_version("1.31.0", "1.31.1")
Beispiel #4
0
    def plot_contour(self,
                     field_or_fields_container,
                     notebook=None,
                     shell_layers=None,
                     off_screen=None,
                     show_axes=True,
                     meshed_region=None,
                     **kwargs):
        """Plot the contour result on its mesh support.

        You cannot plot a fields container containing results at several
        time steps.

        Parameters
        ----------
        field_or_fields_container : dpf.core.Field or dpf.core.FieldsContainer
            Field or field container that contains the result to plot.
        notebook : bool, optional
            Whether to plot a static image within an iPython notebook
            if available. The default is `None`, in which case an attempt is
            made to plot a static imaage within an iPython notebook. When ``False``,
            a plot external to the notebook is generated with an interactive window.
            When ``True``, a plot is always generated within a notebook.
        shell_layers : core.shell_layers, optional
            Enum used to set the shell layers if the model to plot
            contains shell elements.
        off_screen : bool, optional
            Whether to render off screen, which is useful for automated
            screenshots. The default is ``None``.
        show_axes : bool, optional
            Whether to show a VTK axes widget. The default is ``True``.
        **kwargs : optional
            Additional keyword arguments for the plotter. For more information,
            see ``help(pyvista.plot)``.
        """
        if not sys.warnoptions:
            import warnings

            warnings.simplefilter("ignore")

        if isinstance(field_or_fields_container,
                      (dpf.core.Field, dpf.core.FieldsContainer)):
            fields_container = None
            if isinstance(field_or_fields_container, dpf.core.Field):
                fields_container = dpf.core.FieldsContainer(
                    server=field_or_fields_container._server)
                fields_container.add_label(DefinitionLabels.time)
                fields_container.add_field({DefinitionLabels.time: 1},
                                           field_or_fields_container)
            elif isinstance(field_or_fields_container,
                            dpf.core.FieldsContainer):
                fields_container = field_or_fields_container
        else:
            raise TypeError("Only field or fields_container can be plotted.")

        # pre-loop to check if the there are several time steps
        labels = fields_container.get_label_space(0)
        if DefinitionLabels.complex in labels.keys():
            raise dpf_errors.ComplexPlottingError
        if DefinitionLabels.time in labels.keys():
            first_time = labels[DefinitionLabels.time]
            for i in range(1, len(fields_container)):
                label = fields_container.get_label_space(i)
                if label[DefinitionLabels.time] != first_time:
                    raise dpf_errors.FieldContainerPlottingError

        if meshed_region is not None:
            mesh = meshed_region
        else:
            mesh = self._mesh

        # get mesh scoping
        location = None
        component_count = None
        name = None

        # pre-loop to get location and component count
        for field in fields_container:
            if len(field.data) != 0:
                location = field.location
                component_count = field.component_count
                name = field.name.split("_")[0]
                break

        if location == locations.nodal:
            mesh_location = mesh.nodes
        elif location == locations.elemental:
            mesh_location = mesh.elements
        else:
            raise ValueError(
                "Only elemental or nodal location are supported for plotting.")

        # pre-loop: check if shell layers for each field, if yes, set the shell layers
        changeOp = core.Operator("change_shellLayers")
        for field in fields_container:
            shell_layer_check = field.shell_layers
            if shell_layer_check in [
                    eshell_layers.topbottom,
                    eshell_layers.topbottommid,
            ]:
                changeOp.inputs.fields_container.connect(fields_container)
                sl = eshell_layers.top
                if shell_layers is not None:
                    if not isinstance(shell_layers, eshell_layers):
                        raise TypeError(
                            "shell_layer attribute must be a core.shell_layers instance."
                        )
                    sl = shell_layers
                changeOp.inputs.e_shell_layer.connect(
                    sl.value)  # top layers taken
                fields_container = changeOp.get_output(
                    0, core.types.fields_container)
                break

        # Merge field data into a single array
        if component_count > 1:
            overall_data = np.full((len(mesh_location), component_count),
                                   np.nan)
        else:
            overall_data = np.full(len(mesh_location), np.nan)

        for field in fields_container:
            ind, mask = mesh_location.map_scoping(field.scoping)
            overall_data[ind] = field.data[mask]

        # create the plotter and add the meshes
        background = kwargs.pop("background", None)
        cpos = kwargs.pop("cpos", None)
        return_cpos = kwargs.pop("return_cpos", None)

        # plotter = pv.Plotter(notebook=notebook, off_screen=off_screen)
        if notebook is not None:
            self._internal_plotter._plotter.notebook = notebook
        if off_screen is not None:
            self._internal_plotter._plotter.off_screen = off_screen

        # add meshes
        kwargs.setdefault("show_edges", True)
        kwargs.setdefault("nan_color", "grey")
        kwargs.setdefault("stitle", name)
        text = kwargs.pop('text', None)
        if text is not None:
            self._internal_plotter._plotter.add_text(text,
                                                     position='lower_edge')
        self._internal_plotter._plotter.add_mesh(mesh.grid,
                                                 scalars=overall_data,
                                                 **kwargs)

        if background is not None:
            self._internal_plotter._plotter.set_background(background)

        if cpos is not None:
            self._internal_plotter._plotter.camera_position = cpos

        # show result
        if show_axes:
            self._internal_plotter._plotter.add_axes()
        if return_cpos is None:
            return self._internal_plotter._plotter.show()
        else:
            import pyvista as pv
            pv_version = pv.__version__
            version_to_reach = '0.32.0'
            meet_ver = meets_version(pv_version, version_to_reach)
            if meet_ver:
                return self._internal_plotter._plotter.show(
                    return_cpos=return_cpos)
            else:
                txt = """To use the return_cpos option, please upgrade
                your pyvista module with a version higher than """
                txt += version_to_reach
                raise core.errors.DpfVersionNotSupported(version_to_reach, txt)
Beispiel #5
0
    def add_field(self,
                  field,
                  meshed_region=None,
                  show_max=False,
                  show_min=False,
                  label_text_size=30,
                  label_point_size=20,
                  **kwargs):
        name = field.name.split("_")[0]
        try:
            import pyvista as pv
        except ModuleNotFoundError:
            raise ModuleNotFoundError(
                "To use plotting capabilities, please install pyvista "
                "with :\n pip install pyvista>=0.24.0")
        pv_version = pv.__version__
        version_to_reach = '0.30.0'
        meet_ver = meets_version(pv_version, version_to_reach)
        if meet_ver:
            # use scalar_bar_args
            scalar_bar_args = {'title': name}
            kwargs.setdefault("scalar_bar_args", scalar_bar_args)
        else:
            # use stitle
            kwargs.setdefault("stitle", name)
        kwargs.setdefault("show_edges", True)
        kwargs.setdefault("nan_color", "grey")

        # get the meshed region location
        if meshed_region is None:
            meshed_region = field.meshed_region
        location = field.location
        if location == locations.nodal:
            mesh_location = meshed_region.nodes
        elif location == locations.elemental:
            mesh_location = meshed_region.elements
            if show_max or show_min:
                warnings.warn(
                    "`show_max` and `show_min` is only supported for Nodal results."
                )
                show_max = False
                show_min = False
        else:
            raise ValueError(
                "Only elemental or nodal location are supported for plotting.")
        component_count = field.component_count
        if component_count > 1:
            overall_data = np.full((len(mesh_location), component_count),
                                   np.nan)
        else:
            overall_data = np.full(len(mesh_location), np.nan)
        ind, mask = mesh_location.map_scoping(field.scoping)
        overall_data[ind] = field.data[mask]

        # plot
        kwargs_in = self._sort_supported_kwargs(
            bound_method=self._plotter.add_mesh, **kwargs)
        self._plotter.add_mesh(meshed_region.grid,
                               scalars=overall_data,
                               **kwargs_in)

        if show_max or show_min:
            # Get Min-Max for the field
            min_max = core.operators.min_max.min_max()
            min_max.inputs.connect(field)

        # Add Min and Max Labels
        labels = []
        grid_points = []
        if show_max:
            max_field = min_max.outputs.field_max()
            # Get Node ID at max.
            node_id_at_max = max_field.scoping.id(0)
            labels.append(
                f"Max: {max_field.data[0]:.2f}\nNodeID: {node_id_at_max}")
            # Get Node index at max value.
            node_index_at_max = meshed_region.nodes.scoping.index(
                node_id_at_max)
            # Append the corresponding Grid Point.
            grid_points.append(meshed_region.grid.points[node_index_at_max])

        if show_min:
            min_field = min_max.outputs.field_min()
            # Get Node ID at min.
            node_id_at_min = min_field.scoping.id(0)
            labels.append(
                f"Min: {min_field.data[0]:.2f}\nNodeID: {node_id_at_min}")
            # Get Node index at min. value.
            node_index_at_min = meshed_region.nodes.scoping.index(
                node_id_at_min)
            # Append the corresponding Grid Point.
            grid_points.append(meshed_region.grid.points[node_index_at_min])

        # Plot labels:
        for index, grid_point in enumerate(grid_points):
            self._plotter.add_point_labels(grid_point, [labels[index]],
                                           font_size=label_text_size,
                                           point_size=label_point_size)
Beispiel #6
0
import numpy as np
import pytest

from ansys import dpf
from ansys.dpf.core import Scoping
from ansys.dpf.core import errors as dpf_errors
from ansys.dpf.core.check_version import meets_version, get_server_version

serv = dpf.core.start_local_server("127.0.0.1", 50075)
SERVER_VERSION_HIGHER_THAN_2_0 = meets_version(get_server_version(serv), "2.1")


# serv.shutdown()


def test_create_scoping():
    scop = Scoping()
    assert scop._message.id


def test_createbycopy_scoping():
    scop = Scoping()
    scop2 = Scoping(scoping=scop._message)
    assert scop._message.id == scop2._message.id


def test_create_scoping_with_ids_location():
    scop = Scoping(ids=[1, 2, 3, 5, 8, 9, 10], location=dpf.core.locations.elemental)
    assert scop._message.id
    assert scop.ids == [1, 2, 3, 5, 8, 9, 10]
    assert scop.location == dpf.core.locations.elemental