From 03dd087daf3c1577c3d96e9513f263997c9c7bee Mon Sep 17 00:00:00 2001 From: PProfizi <100710998+PProfizi@users.noreply.github.com> Date: Wed, 19 Oct 2022 11:17:37 +0200 Subject: [PATCH] Fix animations for deform_by=result, as well as when animating a stress field with no deform_by argument. (#570) (cherry picked from commit 4f293923b6d59412aa880545c5ae539014f191f5) --- ansys/dpf/core/fields_container.py | 12 ++-- examples/05-plotting/06-animate_results.py | 8 ++- tests/test_animator.py | 80 ++++++++++------------ 3 files changed, 49 insertions(+), 51 deletions(-) diff --git a/ansys/dpf/core/fields_container.py b/ansys/dpf/core/fields_container.py index 83a6d83640..5ac36c5c31 100644 --- a/ansys/dpf/core/fields_container.py +++ b/ansys/dpf/core/fields_container.py @@ -536,6 +536,11 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, **kwargs): deform = False if deform_by and not isinstance(deform_by, dpf.core.FieldsContainer): deform_by = deform_by.eval() + 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(self)}).") else: deform = False if deform: @@ -561,15 +566,12 @@ def animate(self, save_as=None, deform_by=None, scale_factor=1.0, **kwargs): # 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 else: scale_factor = None - scale_factor_fc = dpf.core.animator.scale_factor_to_fc(1.0, self) - extract_scale_factor_op = dpf.core.operators.utility.extract_field(scale_factor_fc) - add_op = dpf.core.operators.utility.forward_field(extract_scale_factor_op) - wf.set_output_name("deform_by", add_op.outputs.field) wf.set_output_name("to_render", extract_field_op.outputs.field) wf.progress_bar = False - add_op.progress_bar = False loop_over = self.get_time_scoping() frequencies = self.time_freq_support.time_frequencies diff --git a/examples/05-plotting/06-animate_results.py b/examples/05-plotting/06-animate_results.py index 5c9ef87833..7faf9e279a 100644 --- a/examples/05-plotting/06-animate_results.py +++ b/examples/05-plotting/06-animate_results.py @@ -7,7 +7,6 @@ shown with the arguments available. """ -# sphinx_gallery_thumbnail_number = 1 from ansys.dpf import core as dpf from ansys.dpf.core import examples @@ -43,6 +42,9 @@ # - Showing the static geometry if the fields are not nodal 3D vector fields. # stress_fields.animate() +# One can deactivate by default animation by self using deform_by=False +# displacement_fields.animate(deform_by=False) + # Change the scale factor using a number/a list of numbers for a uniform constant/varying scaling. # displacement_fields.animate(deform_by=True, scale_factor=10., # show_axes=True) @@ -62,8 +64,8 @@ # - a Result giving nodal 3D vectorial length fields # stress_fields.animate(deform_by=model.results.displacement.on_all_time_freqs()) # - an Operator which outputs nodal 3D vectorial length fields -# stress_fields.animate(deform_by=model.results.displacement) - +# stress_fields.animate(deform_by=model.results.displacement.on_all_time_freqs) +# It must evaluate to a FieldsContainer of same length as the one being animated. # Save the animation using "save_as" with a target path with the desired format as extension. # (accepts .gif, .avi or .mp4, see pyvista.Plotter.open_movie) diff --git a/tests/test_animator.py b/tests/test_animator.py index c264fa426f..1d6bb0a85d 100644 --- a/tests/test_animator.py +++ b/tests/test_animator.py @@ -58,7 +58,7 @@ def test_animator_animate_raise_no_workflow(): assert "self.workflow" in e -def test_animator_animate(remove_gifs, displacement_fields): +def test_animator_animate(displacement_fields): frequencies = displacement_fields.time_freq_support.time_frequencies loop_over = displacement_fields.get_time_scoping() loop_over_field = dpf.fields_factory.field_from_array(frequencies.data[loop_over.ids-1]) @@ -72,8 +72,6 @@ def test_animator_animate(remove_gifs, displacement_fields): an = Animator(wf) an.animate(loop_over=loop_over_field) - # assert os.path.isfile(gif_name) - # assert os.path.getsize(gif_name) > 600000 def test_animator_animate_raise_wrong_scale_factor(remove_gifs, displacement_fields): @@ -94,19 +92,25 @@ def test_animator_animate_raise_wrong_scale_factor(remove_gifs, displacement_fie assert "Argument scale_factor must be" in e -def test_animator_animate_fields_container(remove_gifs, displacement_fields): +def test_animator_animate_fields_container(displacement_fields): displacement_fields.animate() - # assert os.path.isfile(gif_name) - # assert os.path.getsize(gif_name) > 600000 -def test_animator_animate_fields_container_deform_by_false(remove_gifs, displacement_fields): +def test_animator_animate_fields_container_deform_by_false(displacement_fields): displacement_fields.animate(deform_by=False) - # assert os.path.isfile(gif_name) - # assert os.path.getsize(gif_name) > 600000 -def test_animator_animate_fields_container_eqv_partial_scoping(remove_gifs): +def test_animator_animate_fields_container_eqv(): + model = dpf.Model(examples.msup_transient) + time_scoping = dpf.time_freq_scoping_factory.scoping_by_sets( + list(range(5, 20))) + stress_result = model.results.stress.on_time_scoping(time_scoping) + + stress_fields = stress_result.on_location(dpf.common.locations.nodal).eval() + stress_fields.animate() + + +def test_animator_animate_fields_container_eqv_partial_scoping(): model = dpf.Model(examples.msup_transient) time_scoping = dpf.time_freq_scoping_factory.scoping_by_sets( list(range(5, 20))) @@ -121,23 +125,17 @@ def test_animator_animate_fields_container_eqv_partial_scoping(remove_gifs): stress_fields = stress_result.on_location(dpf.common.locations.nodal).eval() stress_fields.animate(deform_by=displacement_result, scale_factor=20., framerate=1.) - # assert os.path.isfile(gif_name) - # assert os.path.getsize(gif_name) > 400000 -def test_animator_animate_fields_container_one_component(remove_gifs, displacement_fields): +def test_animator_animate_fields_container_one_component(displacement_fields): displacement_fields.select_component(0).animate() - # assert os.path.isfile(gif_name) - # assert os.path.getsize(gif_name) > 600000 -def test_animator_animate_fields_container_deform_by_convert_unit(remove_gifs, displacement_fields): +def test_animator_animate_fields_container_deform_by_convert_unit(displacement_fields): new_displacement_fields = displacement_fields.deep_copy() dpf.operators.math.unit_convert_fc( fields_container=new_displacement_fields, unit_name="mm") displacement_fields.animate(deform_by=new_displacement_fields) - # assert os.path.isfile(gif_name) - # assert os.path.getsize(gif_name) > 600000 def test_animator_animate_fields_container_scale_factor_raise(displacement_fields): @@ -146,72 +144,68 @@ def test_animator_animate_fields_container_scale_factor_raise(displacement_field assert "Argument scale_factor must be" in e -def test_animator_animate_fields_container_deform_by_result(remove_gifs): +def test_animator_animate_fields_container_deform_by_result(): model = dpf.Model(examples.msup_transient) displacement_result = model.results.displacement.on_all_time_freqs displacement_fields = displacement_result.eval() displacement_fields.animate(deform_by=displacement_result) - # assert os.path.isfile(gif_name) - # assert os.path.getsize(gif_name) > 600000 -def test_animator_animate_fields_container_deform_by_operator(remove_gifs): +def test_animator_animate_fields_container_deform_by_result_raise(): + model = dpf.Model(examples.msup_transient) + displacement_result = model.results.displacement + displacement_fields = displacement_result.on_all_time_freqs.eval() + with pytest.raises(ValueError) as e: + displacement_fields.animate(deform_by=displacement_result.on_first_time_freq) + assert "'deform_by' argument must result in a FieldsContainer" in e + + +def test_animator_animate_fields_container_deform_by_operator(): model = dpf.Model(examples.msup_transient) displacement_op = model.results.displacement.on_all_time_freqs() displacement_fields = displacement_op.eval() displacement_fields.animate(deform_by=displacement_op) - # assert os.path.isfile(gif_name) - # assert os.path.getsize(gif_name) > 600000 -def test_animator_animate_fields_container_scale_factor_int(remove_gifs, displacement_fields): +def test_animator_animate_fields_container_scale_factor_int(displacement_fields): displacement_fields.animate(scale_factor=2) - # assert os.path.isfile(gif_name) - # assert os.path.getsize(gif_name) > 600000 -def test_animator_animate_fields_container_scale_factor_float(remove_gifs, displacement_fields): +def test_animator_animate_fields_container_scale_factor_float(displacement_fields): displacement_fields.animate(scale_factor=2.0) - # assert os.path.isfile(gif_name) - # assert os.path.getsize(gif_name) > 600000 -def test_animator_animate_fields_container_scale_factor_zero(remove_gifs, displacement_fields): +def test_animator_animate_fields_container_scale_factor_zero(displacement_fields): displacement_fields.animate(scale_factor=0.0) - # assert os.path.isfile(gif_name) - # assert os.path.getsize(gif_name) > 600000 -def test_animator_animate_fields_container_scale_factor_list(remove_gifs, displacement_fields): +def test_animator_animate_fields_container_scale_factor_list(displacement_fields): scale_factor_list = [2.0]*len(displacement_fields) displacement_fields.animate(scale_factor=scale_factor_list) - # assert os.path.isfile(gif_name) - # assert os.path.getsize(gif_name) > 600000 -def test_animator_animate_fields_container_scale_factor_raise_list_len(remove_gifs, - displacement_fields): +def test_animator_animate_fields_container_scale_factor_raise_list_len(displacement_fields): scale_factor_list = [2.0]*(len(displacement_fields)-2) with pytest.raises(ValueError) as e: - displacement_fields.animate(save_as=gif_name, scale_factor=scale_factor_list) + displacement_fields.animate(scale_factor=scale_factor_list) assert "The scale_factor list is not the same length" in e -def test_animator_animate_fields_container_scale_factor_field(remove_gifs, displacement_fields): +def test_animator_animate_fields_container_scale_factor_field(displacement_fields): scale_factor_field = dpf.fields_factory.field_from_array(displacement_fields[0].data) with pytest.raises(NotImplementedError) as e: - displacement_fields.animate(save_as=gif_name, scale_factor=scale_factor_field) + displacement_fields.animate(scale_factor=scale_factor_field) assert "Scaling by a Field is not yet implemented." in e -def test_animator_animate_fields_container_scale_factor_fc(remove_gifs, displacement_fields): +def test_animator_animate_fields_container_scale_factor_fc(displacement_fields): fields = [] for f in displacement_fields: fields.append(dpf.fields_factory.field_from_array(f.data)) scale_factor_fc = dpf.fields_container_factory.over_time_freq_fields_container(fields) scale_factor_fc.time_freq_support = displacement_fields.time_freq_support with pytest.raises(NotImplementedError) as e: - displacement_fields.animate(save_as=gif_name, scale_factor=scale_factor_fc) + displacement_fields.animate(scale_factor=scale_factor_fc) assert "Scaling by a FieldsContainer is not yet implemented." in e