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)
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)
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")
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)
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)
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