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 shell layer selection #769

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
5be5b17
Fix elemental scoping if force_elemental nodal is true. Also fixes ht…
janvonrickenbach Oct 29, 2024
b1a8600
Remove duplicate tests
janvonrickenbach Oct 29, 2024
16908d9
Fix boolean conversion and add elements from nodes selection
janvonrickenbach Oct 29, 2024
b4258b7
Remove obsolete tests
janvonrickenbach Oct 29, 2024
b5ecf45
Add more tests for different types of selections
janvonrickenbach Oct 29, 2024
52f4d39
Fix code quality issue
janvonrickenbach Oct 30, 2024
4bec279
Update src/ansys/dpf/post/selection.py
janvonrickenbach Oct 31, 2024
91892eb
Add comment
janvonrickenbach Oct 31, 2024
65720c1
Working version with rescoping at the end of the workflow
janvonrickenbach Oct 31, 2024
5fb222d
Make named selections consistent
janvonrickenbach Oct 31, 2024
bbfac0b
Add additional test for single node selection
janvonrickenbach Nov 25, 2024
06081da
Merge branch 'refs/heads/master' into jvonrick/fix_selections_with_mu…
janvonrickenbach Nov 25, 2024
03a35ae
Initial working version. Shell layer workflow will be removed and she…
janvonrickenbach Nov 27, 2024
9d9d542
Also test averaged nodes
janvonrickenbach Nov 28, 2024
7019a4b
Remove skip duplicate nodes option
janvonrickenbach Nov 28, 2024
87608f5
Make ref results more configurable
janvonrickenbach Nov 28, 2024
1246410
Fix tests
janvonrickenbach Nov 28, 2024
d63ca7d
Merge branch 'refs/heads/jvonrick/fix_selections_with_multiple_bodies…
janvonrickenbach Nov 28, 2024
26b9563
Use enums for shell layers
janvonrickenbach Nov 28, 2024
418bc12
Fix elemental case
janvonrickenbach Nov 28, 2024
1aa2bf0
Make all tests pass. solid results on skin for elemental results curr…
janvonrickenbach Nov 28, 2024
e1ce841
Split test into functions
janvonrickenbach Nov 28, 2024
8bd018f
Simplify reference data
janvonrickenbach Nov 28, 2024
624f451
Add shell layer selection for all simulation types
janvonrickenbach Dec 3, 2024
aa93850
Skip shell layer selection if not shell layers are requested
janvonrickenbach Dec 3, 2024
b8130bd
Merge branch 'refs/heads/master' into jvonrick/add_shell_layer_selection
janvonrickenbach Dec 3, 2024
8564cd8
Fix case where no shell layer is selected
janvonrickenbach Dec 3, 2024
787c3df
Skip manual shell layer extraction for nodal results. Add more tests.
janvonrickenbach Dec 10, 2024
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
8 changes: 8 additions & 0 deletions src/ansys/dpf/post/harmonic_mechanical_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from typing import List, Optional, Tuple, Union
import warnings

from ansys.dpf.core import shell_layers

from ansys.dpf import core as dpf
from ansys.dpf.post import locations
from ansys.dpf.post.dataframe import DataFrame
Expand Down Expand Up @@ -56,6 +58,7 @@ def _get_result_workflow(
phase_angle_cyclic: Union[float, None] = None,
averaging_config: AveragingConfig = AveragingConfig(),
rescoping: Optional[_Rescoping] = None,
shell_layer: Optional[shell_layers] = None,
) -> (dpf.Workflow, Union[str, list[str], None], str):
"""Generate (without evaluating) the Workflow to extract results."""
result_workflow_inputs = _create_result_workflow_inputs(
Expand All @@ -70,6 +73,7 @@ def _get_result_workflow(
sweeping_phase=sweeping_phase,
averaging_config=averaging_config,
rescoping=rescoping,
shell_layer=shell_layer,
)
result_workflows = _create_result_workflows(
server=self._model._server,
Expand All @@ -89,6 +93,7 @@ def _get_result_workflow(
location=location,
force_elemental_nodal=result_workflows.force_elemental_nodal,
averaging_config=averaging_config,
shell_layer=shell_layer,
)

output_wf = _connect_averaging_eqv_and_principal_workflows(result_workflows)
Expand Down Expand Up @@ -135,6 +140,7 @@ def _get_result(
external_layer: Union[bool, List[int]] = False,
skin: Union[bool, List[int]] = False,
averaging_config: AveragingConfig = AveragingConfig(),
shell_layer: Optional[shell_layers] = None,
) -> DataFrame:
"""Extract results from the simulation.

Expand Down Expand Up @@ -211,6 +217,8 @@ def _get_result(
Per default averaging happens across all bodies. The averaging config
can define that averaging happens per body and defines the properties that
are used to define a body.
shell_layer:
Shell layer to extract results for.

Returns
-------
Expand Down
7 changes: 7 additions & 0 deletions src/ansys/dpf/post/modal_mechanical_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"""
from typing import List, Optional, Union

from ansys.dpf.core import shell_layers

from ansys.dpf import core as dpf
from ansys.dpf.post import locations
from ansys.dpf.post.dataframe import DataFrame
Expand Down Expand Up @@ -45,6 +47,7 @@ def _get_result_workflow(
phase_angle_cyclic: Union[float, None] = None,
averaging_config: AveragingConfig = AveragingConfig(),
rescoping: Optional[_Rescoping] = None,
shell_layer: Optional[shell_layers] = None,
) -> (dpf.Workflow, Union[str, list[str], None], str):
"""Generate (without evaluating) the Workflow to extract results."""
result_workflow_inputs = _create_result_workflow_inputs(
Expand All @@ -57,6 +60,7 @@ def _get_result_workflow(
create_operator_callable=self._model.operator,
averaging_config=averaging_config,
rescoping=rescoping,
shell_layer=shell_layer,
)
result_workflows = _create_result_workflows(
server=self._model._server,
Expand Down Expand Up @@ -116,6 +120,7 @@ def _get_result(
external_layer: Union[bool, List[int]] = False,
skin: Union[bool, List[int]] = False,
averaging_config: AveragingConfig = AveragingConfig(),
shell_layer: Optional[int] = None,
) -> DataFrame:
"""Extract results from the simulation.

Expand Down Expand Up @@ -185,6 +190,8 @@ def _get_result(
Per default averaging happens across all bodies. The averaging config
can define that averaging happens per body and defines the properties that
are used to define a body.
shell_layer:
Shell layer to extract results for.

Returns
-------
Expand Down
6 changes: 5 additions & 1 deletion src/ansys/dpf/post/result_workflows/_build_workflow.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import dataclasses
from typing import Callable, List, Optional, Union

from ansys.dpf.core import Operator, Workflow
from ansys.dpf.core import Operator, Workflow, shell_layers
from ansys.dpf.core.available_result import _result_properties
from ansys.dpf.gate.common import locations

Expand Down Expand Up @@ -92,6 +92,7 @@ class _CreateWorkflowInputs:
components_to_extract: list[int]
should_extract_components: bool
averaging_config: AveragingConfig
shell_layer: Optional[shell_layers]
sweeping_phase_workflow_inputs: Optional[_SweepingPhaseWorkflowInputs] = None
rescoping_workflow_inputs: Optional[_Rescoping] = None

Expand Down Expand Up @@ -141,6 +142,7 @@ def _create_result_workflows(
initial_result_wf = _create_initial_result_workflow(
name=create_workflow_inputs.base_name,
server=server,
shell_layer=create_workflow_inputs.shell_layer,
create_operator_callable=create_operator_callable,
)

Expand Down Expand Up @@ -242,6 +244,7 @@ def _create_result_workflow_inputs(
selection: Selection,
create_operator_callable: Callable[[str], Operator],
averaging_config: AveragingConfig,
shell_layer: Optional[shell_layers],
rescoping: Optional[_Rescoping] = None,
amplitude: bool = False,
sweeping_phase: Union[float, None] = 0.0,
Expand Down Expand Up @@ -293,4 +296,5 @@ def _create_result_workflow_inputs(
sweeping_phase_workflow_inputs=sweeping_phase_workflow_inputs,
averaging_config=averaging_config,
rescoping_workflow_inputs=rescoping,
shell_layer=shell_layer,
)
16 changes: 15 additions & 1 deletion src/ansys/dpf/post/result_workflows/_connect_workflow_inputs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from typing import Any, Optional

from ansys.dpf.core import MeshedRegion, Scoping, ScopingsContainer, Workflow
from ansys.dpf.core import (
MeshedRegion,
Scoping,
ScopingsContainer,
Workflow,
shell_layers,
)

from ansys.dpf.post.result_workflows._build_workflow import ResultWorkflows
from ansys.dpf.post.result_workflows._sub_workflows import (
Expand Down Expand Up @@ -86,6 +92,7 @@ def _connect_workflow_inputs(
streams_provider: Any,
data_sources: Any,
averaging_config: AveragingConfig,
shell_layer: Optional[shell_layers] = None,
):
"""Connects the inputs of the initial result workflow.

Expand Down Expand Up @@ -147,6 +154,13 @@ def _connect_workflow_inputs(

initial_result_workflow.connect(_WfNames.mesh, mesh)

if shell_layer is not None:
if _WfNames.shell_layer not in initial_result_workflow.input_names:
raise RuntimeError(
"The shell_layer input is not supported by this workflow."
)
initial_result_workflow.connect(_WfNames.shell_layer, shell_layer.value)

if rescoping_workflow:
rescoping_workflow.connect(_WfNames.mesh, mesh)
if _WfNames.data_sources in rescoping_workflow.input_names:
Expand Down
64 changes: 59 additions & 5 deletions src/ansys/dpf/post/result_workflows/_sub_workflows.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from typing import Union

from ansys.dpf.core import MeshedRegion, StreamsContainer, Workflow, operators
from typing import Optional, Union

from ansys.dpf.core import (
MeshedRegion,
StreamsContainer,
Workflow,
operators,
shell_layers,
)
from ansys.dpf.gate.common import locations

from ansys.dpf.post.misc import _connect_any
Expand Down Expand Up @@ -165,16 +171,64 @@ def _create_norm_workflow(


def _create_initial_result_workflow(
name: str, server, create_operator_callable: _CreateOperatorCallable
name: str,
server,
shell_layer: Optional[shell_layers],
create_operator_callable: _CreateOperatorCallable,
):
initial_result_workflow = Workflow(server=server)

initial_result_op = create_operator_callable(name=name)

initial_result_workflow.set_input_name(_WfNames.mesh, initial_result_op, 7)
initial_result_workflow.set_input_name(_WfNames.location, initial_result_op, 9)

initial_result_workflow.add_operator(initial_result_op)
initial_result_workflow.set_output_name(_WfNames.output_data, initial_result_op, 0)

forward_shell_layer_op = operators.utility.forward()
initial_result_workflow.add_operator(forward_shell_layer_op)
initial_result_workflow.set_input_name(_WfNames.shell_layer, forward_shell_layer_op)

# The next section is only needed, because the shell_layer selection does not
# work for elemental results. If elemental results are requested with a chosen
# shell layer, the shell layer is not selected and the results are split into solids
# and shells. Here, we add an additional shell layer selection and merge_shell_solid
# operator to manually merge the results. If the shell layer was already selected, this
# should do nothing.
if shell_layer is not None:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MichaelNale Just FYI

merge_shell_solid_fields = create_operator_callable(
name="merge::solid_shell_fields"
)
initial_result_workflow.add_operator(merge_shell_solid_fields)
shell_layer_op = operators.utility.change_shell_layers()
shell_layer_op.inputs.merge(True)
initial_result_workflow.add_operator(shell_layer_op)

initial_result_workflow.set_output_name(
_WfNames.output_data, merge_shell_solid_fields, 0
)
shell_layer_op.inputs.fields_container(
initial_result_op.outputs.fields_container
)
_connect_any(
shell_layer_op.inputs.e_shell_layer, forward_shell_layer_op.outputs.any
)

merge_shell_solid_fields.inputs.fields_container(
shell_layer_op.outputs.fields_container_as_fields_container
)

# End section for elemental results with shell layer selection
else:
initial_result_workflow.set_output_name(
_WfNames.output_data, initial_result_op, 0
)

if hasattr(initial_result_op.inputs, "shell_layer"):
_connect_any(
initial_result_op.inputs.shell_layer, forward_shell_layer_op.outputs.any
)

initial_result_workflow.set_input_name(
"time_scoping", initial_result_op.inputs.time_scoping
)
Expand Down
1 change: 1 addition & 0 deletions src/ansys/dpf/post/selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class _WfNames:
result = "result"
input_data = "input_data"
output_data = "output_data"
shell_layer = "shell_layer"


def _is_model_cyclic(is_cyclic: str):
Expand Down
9 changes: 9 additions & 0 deletions src/ansys/dpf/post/static_mechanical_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"""
from typing import List, Optional, Tuple, Union

from ansys.dpf.core import shell_layers

from ansys.dpf import core
from ansys.dpf.post import locations
from ansys.dpf.post.dataframe import DataFrame
Expand Down Expand Up @@ -41,6 +43,7 @@ def _get_result_workflow(
phase_angle_cyclic: Union[float, None] = None,
averaging_config: AveragingConfig = AveragingConfig(),
rescoping: Optional[_Rescoping] = None,
shell_layer: Optional[shell_layers] = None,
) -> (core.Workflow, Union[str, list[str], None], str):
"""Generate (without evaluating) the Workflow to extract results."""
result_workflow_inputs = _create_result_workflow_inputs(
Expand All @@ -53,6 +56,7 @@ def _get_result_workflow(
create_operator_callable=self._model.operator,
averaging_config=averaging_config,
rescoping=rescoping,
shell_layer=shell_layer,
)
result_workflows = _create_result_workflows(
server=self._model._server,
Expand All @@ -72,6 +76,7 @@ def _get_result_workflow(
location=location,
force_elemental_nodal=result_workflows.force_elemental_nodal,
averaging_config=averaging_config,
shell_layer=shell_layer,
)

output_wf = _connect_averaging_eqv_and_principal_workflows(result_workflows)
Expand Down Expand Up @@ -115,6 +120,7 @@ def _get_result(
external_layer: Union[bool, List[int]] = False,
skin: Union[bool, List[int]] = False,
averaging_config: AveragingConfig = AveragingConfig(),
shell_layer: Optional[int] = None,
) -> DataFrame:
"""Extract results from the simulation.

Expand Down Expand Up @@ -186,6 +192,8 @@ def _get_result(
Per default averaging happens across all bodies. The averaging config
can define that averaging happens per body and defines the properties that
are used to define a body.
shell_layer:
Shell layer to extract results for.

Returns
-------
Expand Down Expand Up @@ -234,6 +242,7 @@ def _get_result(
phase_angle_cyclic=phase_angle_cyclic,
averaging_config=averaging_config,
rescoping=rescoping,
shell_layer=shell_layer,
)

# Evaluate the workflow
Expand Down
7 changes: 7 additions & 0 deletions src/ansys/dpf/post/transient_mechanical_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"""
from typing import List, Optional, Tuple, Union

from ansys.dpf.core import shell_layers

from ansys.dpf import core as dpf
from ansys.dpf.post import locations
from ansys.dpf.post.dataframe import DataFrame
Expand Down Expand Up @@ -43,6 +45,7 @@ def _get_result_workflow(
selection: Union[Selection, None] = None,
averaging_config: AveragingConfig = AveragingConfig(),
rescoping: Optional[_Rescoping] = None,
shell_layer: Optional[shell_layers] = None,
) -> (dpf.Workflow, Union[str, list[str], None], str):
"""Generate (without evaluating) the Workflow to extract results."""
result_workflow_inputs = _create_result_workflow_inputs(
Expand All @@ -55,6 +58,7 @@ def _get_result_workflow(
create_operator_callable=self._model.operator,
averaging_config=averaging_config,
rescoping=rescoping,
shell_layer=shell_layer,
)
result_workflows = _create_result_workflows(
server=self._model._server,
Expand Down Expand Up @@ -115,6 +119,7 @@ def _get_result(
external_layer: Union[bool, List[int]] = False,
skin: Union[bool, List[int]] = False,
averaging_config: AveragingConfig = AveragingConfig(),
shell_layer: Optional[shell_layers] = None,
) -> DataFrame:
"""Extract results from the simulation.

Expand Down Expand Up @@ -180,6 +185,8 @@ def _get_result(
Per default averaging happens across all bodies. The averaging config
can define that averaging happens per body and defines the properties that
are used to define a body.
shell_layer:
Shell layer to extract results for.

Returns
-------
Expand Down
Loading
Loading