|
| 1 | +.. _ref_plotting_data_on_deformed_mesh: |
| 2 | + |
| 3 | +============================== |
| 4 | +Plotting data on deformed mesh |
| 5 | +============================== |
| 6 | + |
| 7 | +.. |Model| replace:: :class:`Model <ansys.dpf.core.model.Model>` |
| 8 | +.. |MeshedRegion| replace:: :class:`MeshedRegion <ansys.dpf.core.meshed_region.MeshedRegion>` |
| 9 | +.. |Field| replace:: :class:`Field<ansys.dpf.core.field.Field>` |
| 10 | +.. |FieldsContainer| replace:: :class:`FieldsContainer<ansys.dpf.core.field.Field>` |
| 11 | +.. |MeshesContainer| replace:: :class:`MeshesContainer <ansys.dpf.core.meshes_container.MeshesContainer>`, |
| 12 | + |
| 13 | +This tutorial shows how to plot data on the deformed mesh. For more detailed information on plotting data |
| 14 | +check the :ref:`ref_plotting_data_on_the_mesh` tutorial. |
| 15 | + |
| 16 | +Define the data |
| 17 | +--------------- |
| 18 | + |
| 19 | +In this tutorial we will download a simulation result file available |
| 20 | +in our ``Examples`` package: |
| 21 | + |
| 22 | +.. code-block:: python |
| 23 | +
|
| 24 | + # Import the ``ansys.dpf.core`` module, including examples files and operators subpackage |
| 25 | + from ansys.dpf import core as dpf |
| 26 | + from ansys.dpf.core import examples |
| 27 | + from ansys.dpf.core import operators as ops |
| 28 | + # Define the result file |
| 29 | + result_file = examples.find_multishells_rst() |
| 30 | +
|
| 31 | +The |Model| is a helper designed to give shortcuts to access the analysis results |
| 32 | +metadata, by opening a DataSources or a Streams, and to instanciate results provider for it. |
| 33 | + |
| 34 | +Printing the model displays the available results. |
| 35 | + |
| 36 | +.. code-block:: python |
| 37 | +
|
| 38 | + # Create the model |
| 39 | + my_model = dpf.Model(data_sources=result_file) |
| 40 | + # Print the model |
| 41 | + print(my_model) |
| 42 | +
|
| 43 | +.. rst-class:: sphx-glr-script-out |
| 44 | + |
| 45 | + .. jupyter-execute:: |
| 46 | + :hide-code: |
| 47 | + |
| 48 | + from ansys.dpf import core as dpf |
| 49 | + from ansys.dpf.core import examples |
| 50 | + from ansys.dpf.core import operators as ops |
| 51 | + result_file = examples.find_multishells_rst() |
| 52 | + my_model = dpf.Model(data_sources=result_file) |
| 53 | + print(my_model) |
| 54 | + |
| 55 | + |
| 56 | +To deform the mesh we need a result with a homogeneous unit dimension, a distance unit. |
| 57 | +Thus, to deform the mesh we need the displacement result. |
| 58 | + |
| 59 | +Extract the displacements results from the model: |
| 60 | + |
| 61 | +.. code-block:: python |
| 62 | +
|
| 63 | + # Get the displacement results |
| 64 | + my_disp_result = my_model.results.displacement |
| 65 | +
|
| 66 | +We need to extract the data we want to plot on the deformed mesh. |
| 67 | + |
| 68 | +Mind that the results location must be of type ``Elemental`` or ``Nodal``. We choose |
| 69 | +to work with the XX stress tensor component result. |
| 70 | + |
| 71 | +Fot more information about extracting results from a result file check |
| 72 | +the :ref:`ref_tutorials_import_data` tutorials section. |
| 73 | + |
| 74 | +.. code-block:: python |
| 75 | +
|
| 76 | + # Extract the stress result |
| 77 | + my_stress = my_model.results.stress() |
| 78 | +
|
| 79 | +As the stress result is in a ``ElementalNodal`` location we have to change it. |
| 80 | +Here we define the new location with a input of the |
| 81 | +:class:`stress() <ansys.dpf.core.operators.result.stress.stress>` operator. |
| 82 | + |
| 83 | +.. code-block:: python |
| 84 | +
|
| 85 | + # Define the desired location as an input of the results operator |
| 86 | + my_stress.inputs.requested_location(dpf.locations.nodal) |
| 87 | + # Get the result (the stress result operator gives an FieldsContainer as an output) |
| 88 | + fc_stress = my_stress.eval() |
| 89 | +
|
| 90 | +To get the results only for the XX stress component we have to use |
| 91 | +the :func:`select_component() <ansys.dpf.core.fields_container.FieldsContainer.select_component>` |
| 92 | +method: |
| 93 | + |
| 94 | +.. code-block:: python |
| 95 | +
|
| 96 | + # Define the component to get. |
| 97 | + # The stress tensor has 6 components per elementary data (symmetrical tensor XX,YY,ZZ,XY,YZ,XZ). |
| 98 | + # So we get the component of index=0 |
| 99 | + fc_stress_XX = fc_stress.select_component(index=0) |
| 100 | +
|
| 101 | +Plot deformed geometry |
| 102 | +---------------------- |
| 103 | + |
| 104 | +Here we use the plot [1]_ method. For different approaches check the :ref:`ref_plotting_data_on_the_mesh` tutorial. |
| 105 | + |
| 106 | +The geometry can be defined by a |MeshedRegion| or by a |MeshesContainer|. |
| 107 | + |
| 108 | +Define the |MeshedRegion| from the |Model|: |
| 109 | + |
| 110 | +.. code-block:: python |
| 111 | +
|
| 112 | + # Define the meshed region |
| 113 | + my_meshed_region = my_model.metadata.meshed_region |
| 114 | +
|
| 115 | +There are different ways to obtain a |MeshesContainer|. |
| 116 | + |
| 117 | +Here we get a |MeshesContainer| by using the :class:`split_mesh <ansys.dpf.core.operators.mesh.split_mesh.split_mesh>` |
| 118 | +operator. It splits the mesh by material by default: |
| 119 | + |
| 120 | +.. code-block:: python |
| 121 | +
|
| 122 | + # Define the meshed region |
| 123 | + my_meshes = ops.mesh.split_mesh(mesh=my_meshed_region).eval() |
| 124 | +
|
| 125 | +The geometry can be deformed by a :class:`Result <ansys.dpf.core.results.Result>` object, |
| 126 | +an :class:`Operator<ansys.dpf.core.dpf_operator.Operator>`, a :class:`Field<ansys.dpf.core.field.Field>` |
| 127 | +or a :class:`FieldsContainer<ansys.dpf.core.field.Field>`. |
| 128 | + |
| 129 | +The procedures are the same for a |MeshedRegion| and a |MeshesContainer|. For this reason we will show only |
| 130 | +one plot for the |MeshesContainer| |
| 131 | + |
| 132 | +.. code-block:: python |
| 133 | +
|
| 134 | + # Define the plot formating |
| 135 | + my_scale_factor = 0.001 |
| 136 | + my_window_size=[350,350] |
| 137 | + # Plot the XX stress tensor component results on a MeshedRegion deformed by: |
| 138 | + # a) a Result object |
| 139 | + my_meshed_region.plot( deform_by=my_disp_result, |
| 140 | + scale_factor=my_scale_factor, |
| 141 | + text="a", |
| 142 | + window_size=my_window_size,) |
| 143 | + # b) an Operator |
| 144 | + my_disp_op = my_disp_result() |
| 145 | + my_meshed_region.plot( deform_by=my_disp_op, |
| 146 | + scale_factor=my_scale_factor, |
| 147 | + text="b", |
| 148 | + window_size=my_window_size,) |
| 149 | + # c) a FieldsContainer |
| 150 | + my_disp_fc = my_disp_result.eval() |
| 151 | + my_meshed_region.plot( deform_by=my_disp_fc, |
| 152 | + scale_factor=my_scale_factor, |
| 153 | + text="c", |
| 154 | + window_size=my_window_size,) |
| 155 | + # d) a Field |
| 156 | + my_disp_field = my_disp_fc[0] |
| 157 | + my_meshed_region.plot( deform_by=my_disp_field, |
| 158 | + scale_factor=my_scale_factor, |
| 159 | + text="d", |
| 160 | + window_size=my_window_size) |
| 161 | +
|
| 162 | + # Plot the XX stress tensor component results on a MeshesContainer deformed by a Field |
| 163 | + my_meshes.plot( deform_by=my_disp_field, |
| 164 | + scale_factor=my_scale_factor, |
| 165 | + text="e", |
| 166 | + window_size=my_window_size) |
| 167 | +
|
| 168 | +.. rst-class:: sphx-glr-script-out |
| 169 | + |
| 170 | + .. jupyter-execute:: |
| 171 | + :hide-code: |
| 172 | + |
| 173 | + my_meshed_region = my_model.metadata.meshed_region |
| 174 | + my_meshes = ops.mesh.split_mesh(mesh=my_meshed_region).eval() |
| 175 | + my_disp_result = my_model.results.displacement |
| 176 | + my_stress = my_model.results.stress() |
| 177 | + my_stress.inputs.requested_location(dpf.locations.nodal) |
| 178 | + fc_stress = my_stress.eval() |
| 179 | + my_disp_result = my_model.results.displacement |
| 180 | + my_stress = my_model.results.stress() |
| 181 | + my_scale_factor = 0.001 |
| 182 | + my_window_size=[350,350] |
| 183 | + my_meshed_region.plot( deform_by=my_disp_result, |
| 184 | + scale_factor=my_scale_factor, |
| 185 | + text="a", |
| 186 | + window_size=my_window_size) |
| 187 | + my_disp_op = my_disp_result() |
| 188 | + my_meshed_region.plot( deform_by=my_disp_op, |
| 189 | + scale_factor=my_scale_factor, |
| 190 | + text="b", |
| 191 | + window_size=my_window_size) |
| 192 | + my_disp_fc = my_disp_result.eval() |
| 193 | + my_meshed_region.plot( deform_by=my_disp_fc, |
| 194 | + scale_factor=my_scale_factor, |
| 195 | + text="c", |
| 196 | + font_size=5, |
| 197 | + window_size=my_window_size) |
| 198 | + my_disp_field = my_disp_fc[0] |
| 199 | + my_meshed_region.plot( deform_by=my_disp_field, |
| 200 | + scale_factor=my_scale_factor, |
| 201 | + text="d", |
| 202 | + window_size=my_window_size) |
| 203 | + my_meshes.plot( deform_by=my_disp_field, |
| 204 | + scale_factor=my_scale_factor, |
| 205 | + text="e", |
| 206 | + window_size=my_window_size) |
| 207 | + |
| 208 | +Plot data on the deformed geometry |
| 209 | +---------------------------------- |
| 210 | + |
| 211 | +Plot the data on its mesh support |
| 212 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 213 | + |
| 214 | +Plotting the data in DPF means plotting the |Field| or |FieldsContainer| that contains the data. |
| 215 | + |
| 216 | +Plot the stress results on the deformed geometry: |
| 217 | + |
| 218 | +.. code-block:: python |
| 219 | +
|
| 220 | + # Define the stress field |
| 221 | + stress_field = fc_stress[0] |
| 222 | + # Plot the results on a deformed geometry. The data is in a: |
| 223 | + # a) Field |
| 224 | + stress_field.plot( deform_by=my_disp_field, |
| 225 | + scale_factor=my_scale_factor) |
| 226 | +
|
| 227 | +.. rst-class:: sphx-glr-script-out |
| 228 | + |
| 229 | + .. jupyter-execute:: |
| 230 | + :hide-code: |
| 231 | + |
| 232 | + stress_field = fc_stress[0] |
| 233 | + stress_field.plot( deform_by=my_disp_field, |
| 234 | + scale_factor=my_scale_factor) |
| 235 | + |
| 236 | +Plot the mesh and add the stress data on top of that |
| 237 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 238 | + |
| 239 | +The data to be plotted in a |MeshedRegion| can be in a |Field| or in a |FieldsContainer| |
| 240 | + |
| 241 | +.. code-block:: python |
| 242 | +
|
| 243 | + # Plot the MeshedRegion and the stress in a Field |
| 244 | + my_meshed_region.plot( field_or_fields_container=stress_field |
| 245 | + deform_by=my_disp_field, |
| 246 | + scale_factor=my_scale_factor) |
| 247 | +
|
| 248 | +.. rst-class:: sphx-glr-script-out |
| 249 | + |
| 250 | + .. jupyter-execute:: |
| 251 | + :hide-code: |
| 252 | + |
| 253 | + my_meshed_region.plot( field_or_fields_container=stress_field, |
| 254 | + deform_by=my_disp_field, |
| 255 | + scale_factor=my_scale_factor) |
| 256 | + |
| 257 | +The data to be plotted in a |MeshesContainer| must be in a |FieldsContainer| |
| 258 | + |
| 259 | +.. code-block:: python |
| 260 | +
|
| 261 | + # Plot the MeshesContainer and the stress in a FieldsContainer |
| 262 | + my_meshes.plot( fields_container=fc_stress |
| 263 | + deform_by=my_disp_field, |
| 264 | + scale_factor=my_scale_factor) |
| 265 | +
|
| 266 | +.. rst-class:: sphx-glr-script-out |
| 267 | + |
| 268 | + .. jupyter-execute:: |
| 269 | + :hide-code: |
| 270 | + |
| 271 | + my_meshed_region.plot( field_or_fields_container=stress_field, |
| 272 | + deform_by=my_disp_field, |
| 273 | + scale_factor=my_scale_factor) |
| 274 | + |
| 275 | +.. rubric:: Footnotes |
| 276 | + |
| 277 | +.. [1] The default plotter settings display the mesh with edges, lighting and axis widget enabled. |
| 278 | +Nevertheless, as we use the `PyVista <https://github.com/pyvista/pyvista>`_ library to create |
| 279 | +the plot you can use additional PyVista arguments (available at: :func:`pyvista.plot`. |
| 280 | + |
| 281 | + |
| 282 | + |
| 283 | + |
| 284 | + |
0 commit comments