Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an associated displacement workflow to a DataFrame #309

Merged
merged 6 commits into from
Mar 6, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Implement DataFrame._disp_wf to associate a lazy displacement evaluat…
…ion for plot and animate
PProfizi committed Mar 3, 2023
commit 961f40c29a7c8de03f9167fbd58971514fc01dbf
25 changes: 16 additions & 9 deletions src/ansys/dpf/post/dataframe.py
Original file line number Diff line number Diff line change
@@ -65,8 +65,7 @@ def __init__(
else:
self._columns = None

# if parent_simulation is not None:
# self._parent_simulation = weakref.ref(parent_simulation)
self._disp_wf = None

self._str = None
self._last_display_width = display_width
@@ -713,18 +712,26 @@ def animate(
"""
deform_by = None
if deform:
try:
simulation = self._parent_simulation()
deform_by = simulation._model.results.displacement.on_time_scoping(
self._fc.get_time_scoping()
)
except Exception as e:
if self._disp_wf is None:
warnings.warn(
UserWarning(
"Displacement result unavailable, "
f"unable to animate on the deformed mesh:\n{e}"
f"unable to animate on the deformed mesh."
)
)
else:
wf = dpf.workflow.Workflow()
forward_op = dpf.operators.utility.forward_fields_container(
server=self._fc._server
)
wf.add_operator(forward_op)
wf.set_input_name("input", forward_op.inputs.fields)
output_input_names = ("output", "input")
wf.connect_with(
left_workflow=self._disp_wf, output_input_names=output_input_names
)

deform_by = forward_op
else:
deform_by = False
return self._fc.animate(
6 changes: 5 additions & 1 deletion src/ansys/dpf/post/harmonic_mechanical_simulation.py
Original file line number Diff line number Diff line change
@@ -270,6 +270,8 @@ def _get_result(
# Evaluate the workflow
fc = wf.get_output("out", core.types.fields_container)

disp_wf = self._generate_disp_workflow(fc, selection)

# Test for empty results
if (len(fc) == 0) or all([len(f) == 0 for f in fc]):
warnings.warn(
@@ -301,11 +303,13 @@ def _get_result(
)

# Return the result wrapped in a DPF_Dataframe
return DataFrame(
df = DataFrame(
data=fc,
columns=column_index,
index=row_index,
)
df._disp_wf = disp_wf
return df

def displacement(
self,
4 changes: 3 additions & 1 deletion src/ansys/dpf/post/modal_mechanical_simulation.py
Original file line number Diff line number Diff line change
@@ -212,7 +212,9 @@ def _get_result(
# Evaluate the workflow
fc = wf.get_output("out", core.types.fields_container)

return self._create_dataframe(fc, location, columns, comp, base_name)
disp_wf = self._generate_disp_workflow(fc, selection)

return self._create_dataframe(fc, location, columns, comp, base_name, disp_wf)

def displacement(
self,
36 changes: 33 additions & 3 deletions src/ansys/dpf/post/simulation.py
Original file line number Diff line number Diff line change
@@ -462,7 +462,34 @@ def _create_components(self, base_name, category, components):
raise ValueError(f"'{category}' is not a valid category value.")
return comp, to_extract, columns

def _create_dataframe(self, fc, location, columns, comp, base_name):
def _generate_disp_workflow(self, fc, selection) -> Union[dpf.Workflow, None]:
# Check displacement is an available result
if not any(
[
result.name == "displacement"
for result in self._model.metadata.result_info.available_results
]
):
return None
# Build an equivalent workflow for displacement for plots and animations
disp_wf = dpf.Workflow(server=fc._server)

disp_op = dpf.operators.result.displacement(
data_sources=self._model.metadata.data_sources,
streams_container=self._model.metadata.streams_provider,
)
# Connect time_scoping (do not connect mesh_scoping as we want to deform the whole mesh)
disp_wf.set_input_name("time_scoping", disp_op.inputs.time_scoping)
disp_wf.connect_with(
selection.time_freq_selection._selection,
output_input_names=("scoping", "time_scoping"),
)
# Expose output
disp_wf.set_output_name("output", disp_op.outputs.fields_container)

return disp_wf

def _create_dataframe(self, fc, location, columns, comp, base_name, disp_wf=None):
# Test for empty results
if (len(fc) == 0) or all([len(f) == 0 for f in fc]):
warnings.warn(
@@ -493,12 +520,15 @@ def _create_dataframe(self, fc, location, columns, comp, base_name):
indexes=row_indexes,
)

# Return the result wrapped in a DPF_Dataframe
return DataFrame(
df = DataFrame(
data=fc,
columns=column_index,
index=row_index,
)
df._disp_wf = disp_wf

# Return the result wrapped in a DPF_Dataframe
return df


class MechanicalSimulation(Simulation, ABC):
4 changes: 3 additions & 1 deletion src/ansys/dpf/post/static_mechanical_simulation.py
Original file line number Diff line number Diff line change
@@ -208,7 +208,9 @@ def _get_result(
# Evaluate the workflow
fc = wf.get_output("out", core.types.fields_container)

return self._create_dataframe(fc, location, columns, comp, base_name)
disp_wf = self._generate_disp_workflow(fc, selection)

return self._create_dataframe(fc, location, columns, comp, base_name, disp_wf)

def displacement(
self,
10 changes: 6 additions & 4 deletions src/ansys/dpf/post/transient_mechanical_simulation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Module containing the ``TransientMechanicalSimulation`` class."""
from typing import List, Tuple, Union

from ansys.dpf import core
from ansys.dpf import core as dpf
from ansys.dpf.post import locations
from ansys.dpf.post.dataframe import DataFrame
from ansys.dpf.post.selection import Selection
@@ -114,7 +114,7 @@ def _get_result(
)

# Initialize a workflow
wf = core.Workflow(server=self._model._server)
wf = dpf.Workflow(server=self._model._server)
wf.progress_bar = False

if category == ResultCategory.equivalent and base_name[0] == "E":
@@ -218,9 +218,11 @@ def _get_result(
# Set the workflow output
wf.set_output_name("out", out)
# Evaluate the workflow
fc = wf.get_output("out", core.types.fields_container)
fc = wf.get_output("out", dpf.types.fields_container)

return self._create_dataframe(fc, location, columns, comp, base_name)
disp_wf = self._generate_disp_workflow(fc, selection)

return self._create_dataframe(fc, location, columns, comp, base_name, disp_wf)

def displacement(
self,