From 5c98e3f19cb76bf761e7b2c792f436214d7106d5 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Mon, 24 Oct 2022 12:04:08 +0200 Subject: [PATCH 1/5] WIP --- ansys/dpf/core/animator.py | 13 ++++++++++--- ansys/dpf/core/fields_container.py | 20 ++++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/ansys/dpf/core/animator.py b/ansys/dpf/core/animator.py index 4305d33b8eb..10b7f4a1dc5 100644 --- a/ansys/dpf/core/animator.py +++ b/ansys/dpf/core/animator.py @@ -75,9 +75,16 @@ def render_field(frame): deform = None if "deform_by" in workflow.output_names: deform = workflow.get_output("deform_by", core.types.field) - self.add_field(field, deform_by=deform, - scale_factor_legend=scale_factor[frame], - **kwargs) + if "mesh" in workflow.output_names: + # Add_mesh + self.add_mesh(workflow.get_output("mesh", core.types.meshed_region), + deform_by=deform, + scale_factor_legend=scale_factor[frame], + **kwargs) + else: + self.add_field(field, deform_by=deform, + scale_factor_legend=scale_factor[frame], + **kwargs) kwargs_in = _sort_supported_kwargs( bound_method=self._plotter.add_text, **freq_kwargs) str_template = "t={0:{2}} {1}" diff --git a/ansys/dpf/core/fields_container.py b/ansys/dpf/core/fields_container.py index 5ac36c5c313..3daa12517ab 100644 --- a/ansys/dpf/core/fields_container.py +++ b/ansys/dpf/core/fields_container.py @@ -489,7 +489,7 @@ def get_time_scoping(self): """ return self.get_label_scoping("time") - def animate(self, save_as=None, deform_by=None, scale_factor=1.0, **kwargs): + def animate(self, save_as=None, deform_by=None, scale_factor=1.0, mesh=None, **kwargs): """Creates an animation based on the Fields contained in the FieldsContainer. This method creates a movie or a gif based on the time ids of a FieldsContainer. @@ -506,6 +506,8 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, **kwargs): scale_factor : float, list, optional Scale factor to apply when warping the mesh. Defaults to 1.0. Can be a list to make scaling frequency-dependent. + mesh : MeshedRegion, MeshesContainer, optional + Mesh support to associate to the fields being animated. """ from ansys.dpf.core.animator import Animator @@ -543,8 +545,8 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, **kwargs): f"!= len(self)={len(self)}).") else: deform = False - if deform: + if deform: scale_factor_fc = dpf.core.animator.scale_factor_to_fc(scale_factor, deform_by) scale_factor_invert = dpf.core.operators.math.invert_fc(scale_factor_fc) # Extraction of the field of interest based on index @@ -560,9 +562,19 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, **kwargs): divide_op = dpf.core.operators.math.component_wise_divide( extract_field_op_2.outputs.field, extract_scale_factor_op.outputs.field) # Get the mesh from the field to render - get_mesh_op = dpf.core.operators.mesh.from_field(extract_field_op.outputs.field) + if mesh is None: + get_mesh_op = dpf.core.operators.mesh.from_field(extract_field_op.outputs.field) + output = get_mesh_op.outputs.mesh + else: + if isinstance(mesh, dpf.core.MeshedRegion): + get_mesh_op = dpf.core.operators.utility.forward(mesh) + output = get_mesh_op.get_output(0, output_type=dpf.core.MeshedRegion) + # wf.set_output_name("mesh", get_mesh_op.outputs.any) + elif isinstance(mesh, dpf.core.MeshesContainer): + raise NotImplementedError("Operator to extract mesh from meshes_container " + "does not exist") # Get the coordinates field from the mesh - get_coordinates_op = dpf.core.operators.mesh.node_coordinates(get_mesh_op.outputs.mesh) + get_coordinates_op = dpf.core.operators.mesh.node_coordinates(output) # Addition to the scaled deformation field add_op = dpf.core.operators.math.add(divide_op.outputs.field, get_coordinates_op.outputs.coordinates_as_field) From 2cffc4d733f7122ca626173747889803c0a0ce0d Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Mon, 24 Oct 2022 15:28:34 +0200 Subject: [PATCH 2/5] WIP --- ansys/dpf/core/fields_container.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/ansys/dpf/core/fields_container.py b/ansys/dpf/core/fields_container.py index 3daa12517ab..d7971d865b2 100644 --- a/ansys/dpf/core/fields_container.py +++ b/ansys/dpf/core/fields_container.py @@ -519,6 +519,23 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, mesh=None, **k # Define the field extraction using the fields_container and indices extract_field_op = dpf.core.operators.utility.extract_field(self) + loop_over = self.get_time_scoping() + frequencies = self.time_freq_support.time_frequencies + if frequencies is None: + raise ValueError("The fields_container has no time_frequencies.") + + set_mesh = False + if len(self.get_field(0).meshed_region.nodes) == 0: + if mesh is None: + raise ValueError("The first field's mesh is empty. Please set the 'mesh' argument.") + else: + set_mesh = True + bind_support_fc = dpf.core.operators.utility.bind_support_fc(self, + support=mesh) + fc = bind_support_fc.eval() + # fc = self + else: + fc = self # TODO /!\ We should be using a mechanical::time_selector, however it is not wrapped. wf.set_input_name("indices", extract_field_op.inputs.indices) # Have to do it this way @@ -531,18 +548,18 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, mesh=None, **k if deform_by is not False: if deform_by is None or isinstance(deform_by, bool): # By default, set deform_by as self if nodal 3D vector field - if self[0].location == dpf.core.common.locations.nodal and \ - self[0].component_count == 3: - deform_by = self + if fc[0].location == dpf.core.common.locations.nodal and \ + fc[0].component_count == 3: + deform_by = fc else: deform = False if deform_by and not isinstance(deform_by, dpf.core.FieldsContainer): deform_by = deform_by.eval() - if len(deform_by) != len(self): + if len(deform_by) != len(fc): raise ValueError("'deform_by' argument must result in a FieldsContainer " "of same length as the animated one " f"(len(deform_by.eval())={len(deform_by)} " - f"!= len(self)={len(self)}).") + f"!= len(self)={len(fc)}).") else: deform = False @@ -585,8 +602,6 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, mesh=None, **k wf.set_output_name("to_render", extract_field_op.outputs.field) wf.progress_bar = False - loop_over = self.get_time_scoping() - frequencies = self.time_freq_support.time_frequencies loop_over_field = dpf.core.fields_factory.field_from_array( frequencies.data[loop_over.ids-1]) loop_over_field.scoping.ids = loop_over.ids From 7ea089577765560719a29b77300bf26d3ab49ad7 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Tue, 25 Oct 2022 11:09:23 +0200 Subject: [PATCH 3/5] Fix error in deformation field for fields_container.py::animate --- ansys/dpf/core/fields_container.py | 46 +++++------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/ansys/dpf/core/fields_container.py b/ansys/dpf/core/fields_container.py index d7971d865b2..f983090083e 100644 --- a/ansys/dpf/core/fields_container.py +++ b/ansys/dpf/core/fields_container.py @@ -489,7 +489,7 @@ def get_time_scoping(self): """ return self.get_label_scoping("time") - def animate(self, save_as=None, deform_by=None, scale_factor=1.0, mesh=None, **kwargs): + def animate(self, save_as=None, deform_by=None, scale_factor=1.0, **kwargs): """Creates an animation based on the Fields contained in the FieldsContainer. This method creates a movie or a gif based on the time ids of a FieldsContainer. @@ -506,8 +506,6 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, mesh=None, **k scale_factor : float, list, optional Scale factor to apply when warping the mesh. Defaults to 1.0. Can be a list to make scaling frequency-dependent. - mesh : MeshedRegion, MeshesContainer, optional - Mesh support to associate to the fields being animated. """ from ansys.dpf.core.animator import Animator @@ -524,18 +522,6 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, mesh=None, **k if frequencies is None: raise ValueError("The fields_container has no time_frequencies.") - set_mesh = False - if len(self.get_field(0).meshed_region.nodes) == 0: - if mesh is None: - raise ValueError("The first field's mesh is empty. Please set the 'mesh' argument.") - else: - set_mesh = True - bind_support_fc = dpf.core.operators.utility.bind_support_fc(self, - support=mesh) - fc = bind_support_fc.eval() - # fc = self - else: - fc = self # TODO /!\ We should be using a mechanical::time_selector, however it is not wrapped. wf.set_input_name("indices", extract_field_op.inputs.indices) # Have to do it this way @@ -548,18 +534,18 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, mesh=None, **k if deform_by is not False: if deform_by is None or isinstance(deform_by, bool): # By default, set deform_by as self if nodal 3D vector field - if fc[0].location == dpf.core.common.locations.nodal and \ - fc[0].component_count == 3: - deform_by = fc + if self[0].location == dpf.core.common.locations.nodal and \ + self[0].component_count == 3: + deform_by = self else: deform = False if deform_by and not isinstance(deform_by, dpf.core.FieldsContainer): deform_by = deform_by.eval() - if len(deform_by) != len(fc): + if len(deform_by) != len(self): raise ValueError("'deform_by' argument must result in a FieldsContainer " "of same length as the animated one " f"(len(deform_by.eval())={len(deform_by)} " - f"!= len(self)={len(fc)}).") + f"!= len(self)={len(self)}).") else: deform = False @@ -578,25 +564,7 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, mesh=None, **k divide_op = dpf.core.operators.math.component_wise_divide( extract_field_op_2.outputs.field, extract_scale_factor_op.outputs.field) - # Get the mesh from the field to render - if mesh is None: - get_mesh_op = dpf.core.operators.mesh.from_field(extract_field_op.outputs.field) - output = get_mesh_op.outputs.mesh - else: - if isinstance(mesh, dpf.core.MeshedRegion): - get_mesh_op = dpf.core.operators.utility.forward(mesh) - output = get_mesh_op.get_output(0, output_type=dpf.core.MeshedRegion) - # wf.set_output_name("mesh", get_mesh_op.outputs.any) - elif isinstance(mesh, dpf.core.MeshesContainer): - raise NotImplementedError("Operator to extract mesh from meshes_container " - "does not exist") - # Get the coordinates field from the mesh - get_coordinates_op = dpf.core.operators.mesh.node_coordinates(output) - # Addition to the scaled deformation field - add_op = dpf.core.operators.math.add(divide_op.outputs.field, - get_coordinates_op.outputs.coordinates_as_field) - wf.set_output_name("deform_by", add_op.outputs.field) - add_op.progress_bar = False + wf.set_output_name("deform_by", divide_op.outputs.field) else: scale_factor = None wf.set_output_name("to_render", extract_field_op.outputs.field) From 26b0f61d89e312e53451dc5cf6e58e847de113b7 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Tue, 25 Oct 2022 11:10:45 +0200 Subject: [PATCH 4/5] Fix error in deformation field for fields_container.py::animate --- ansys/dpf/core/animator.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/ansys/dpf/core/animator.py b/ansys/dpf/core/animator.py index 10b7f4a1dc5..4305d33b8eb 100644 --- a/ansys/dpf/core/animator.py +++ b/ansys/dpf/core/animator.py @@ -75,16 +75,9 @@ def render_field(frame): deform = None if "deform_by" in workflow.output_names: deform = workflow.get_output("deform_by", core.types.field) - if "mesh" in workflow.output_names: - # Add_mesh - self.add_mesh(workflow.get_output("mesh", core.types.meshed_region), - deform_by=deform, - scale_factor_legend=scale_factor[frame], - **kwargs) - else: - self.add_field(field, deform_by=deform, - scale_factor_legend=scale_factor[frame], - **kwargs) + self.add_field(field, deform_by=deform, + scale_factor_legend=scale_factor[frame], + **kwargs) kwargs_in = _sort_supported_kwargs( bound_method=self._plotter.add_text, **freq_kwargs) str_template = "t={0:{2}} {1}" From 616a693765dcae474a5e0f7d0eba09f09549f298 Mon Sep 17 00:00:00 2001 From: "paul.profizi" Date: Tue, 25 Oct 2022 11:16:59 +0200 Subject: [PATCH 5/5] Update example due to fix --- examples/05-plotting/06-animate_results.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/05-plotting/06-animate_results.py b/examples/05-plotting/06-animate_results.py index feae81c8025..fe969ebfe3c 100644 --- a/examples/05-plotting/06-animate_results.py +++ b/examples/05-plotting/06-animate_results.py @@ -92,8 +92,8 @@ # import copy # camera_pos_list = [] -# init_pos = [(2.341999327925363, 2.2535751881950388, 3.241992870018055), -# (0.10000000000000725, 0.01157586026968312, 0.9999935420927001), +# init_pos = [(1.1710286191854873, 1.1276044794551632, 1.62102216127818), +# (0.05000000000000724, 0.006575860269683119, 0.4999935420927001), # (0.0, 0.0, 1.0)] # camera_pos_list.append(init_pos) # for i in range(1, len(displacement_fields)):