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

Support section data from RST #388

Merged
merged 60 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
ec05643
Fix broken link, and port changes from 0.3.1 back to develop
roosre Sep 14, 2023
6a0bbbd
Merge branch 'main' of https://github.com/ansys/pydpf-composites
roosre Sep 21, 2023
d9fc98b
Merge branch 'main' of https://github.com/ansys/pydpf-composites
roosre Sep 27, 2023
18dd8b2
Merge branch 'main' of https://github.com/ansys/pydpf-composites
roosre Oct 13, 2023
2a6b459
Merge branch 'main' of https://github.com/ansys/pydpf-composites
roosre Nov 21, 2023
3e28531
first version that runs with RST file only
roosre Nov 22, 2023
88770bd
ElementInfo with material ID from EBLOCK.
roosre Nov 23, 2023
28c53bd
Merge remote-tracking branch 'remotes/origin/main' into feat/section_…
roosre Nov 23, 2023
1fb4700
update evaluate_failure_criteria to support the different types of la…
roosre Nov 24, 2023
1a0a2ef
add unit test and example for the RST based workflow
roosre Nov 27, 2023
f6133c1
expose layup_model_type and update tests
roosre Nov 28, 2023
e9130b5
Update tests/rst_only_workflow_test.py
roosre Nov 28, 2023
49395f8
Update src/ansys/dpf/composites/layup_info/_layup_info.py
roosre Nov 28, 2023
95859be
Update src/ansys/dpf/composites/layup_info/_add_layup_info_to_mesh.py
roosre Nov 28, 2023
a22db26
Update doc/source/index.rst
roosre Nov 28, 2023
3654488
Update doc/source/index.rst
roosre Nov 28, 2023
b290ddf
Update doc/source/index.rst
roosre Nov 28, 2023
799effe
Update doc/source/index.rst
roosre Nov 28, 2023
6d45f7a
Update doc/source/index.rst
roosre Nov 28, 2023
8a7ab49
Update examples/008_assembly_example.py
roosre Nov 28, 2023
6aa597a
Update examples/011_rst_workflow.py
roosre Nov 28, 2023
6efc1aa
Update examples/011_rst_workflow.py
roosre Nov 28, 2023
404992e
Update examples/011_rst_workflow.py
roosre Nov 28, 2023
a0cc3b7
Update examples/011_rst_workflow.py
roosre Nov 28, 2023
d6d34df
Update examples/011_rst_workflow.py
roosre Nov 28, 2023
0a510f8
Update src/ansys/dpf/composites/_indexer.py
roosre Nov 28, 2023
8fe4079
Update src/ansys/dpf/composites/data_sources.py
roosre Nov 28, 2023
d6c1d13
Update examples/011_rst_workflow.py
roosre Nov 28, 2023
cc41780
Update examples/011_rst_workflow.py
roosre Nov 28, 2023
1fac818
Update src/ansys/dpf/composites/data_sources.py
roosre Nov 28, 2023
1b5aa94
Update src/ansys/dpf/composites/data_sources.py
roosre Nov 28, 2023
bfbb4a1
style checks
roosre Nov 28, 2023
4ee9eec
style check
roosre Nov 28, 2023
1a7c033
style checks
roosre Nov 28, 2023
498fee8
Merge branch 'feat/section_data_from_rst' of https://github.com/ansys…
roosre Nov 28, 2023
4bfe5f9
style checks
roosre Nov 28, 2023
0473a0e
style check
roosre Nov 28, 2023
f33a0af
update doc
roosre Nov 28, 2023
17c6ef7
documentation
roosre Nov 28, 2023
7913763
documentation
roosre Nov 28, 2023
4f45857
update the documentation
roosre Nov 28, 2023
f0455bc
use dpf composite docker image with tag mapdl_section_data
roosre Nov 28, 2023
912b767
temporary change: use mapdl_section_data docker image instead of latest
roosre Nov 28, 2023
b5832bb
documentation: cosmetic changes
roosre Nov 29, 2023
ae0938b
add TokenIgnores for Vale
roosre Nov 29, 2023
a4735d3
Update src/ansys/dpf/composites/_composite_model_impl.py
roosre Nov 29, 2023
7786a69
Update src/ansys/dpf/composites/_indexer.py
roosre Nov 29, 2023
ae23b9a
Update src/ansys/dpf/composites/_indexer.py
roosre Nov 29, 2023
27bc330
Update src/ansys/dpf/composites/_indexer.py
roosre Nov 29, 2023
48d707f
Update src/ansys/dpf/composites/_indexer.py
roosre Nov 29, 2023
6f97e29
improve documentation
roosre Nov 30, 2023
e7f7f1a
additional unit tests to verify the ElementInfoProvider for mixed mod…
roosre Nov 30, 2023
cd67e4d
style check
roosre Nov 30, 2023
ccd3523
cosmetic change
roosre Nov 30, 2023
6fcb0d1
switch back to the latest docker image
roosre Nov 30, 2023
6669299
Merge branch 'feat/section_data_from_rst' of https://github.com/ansys…
roosre Nov 30, 2023
8ccf3e1
style checks
roosre Nov 30, 2023
7f4dcec
Update doc/source/index.rst
roosre Nov 30, 2023
c71e8f8
Skip new tests if the tests are run with an old server
roosre Nov 30, 2023
cd9a5af
run style check
roosre Nov 30, 2023
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
29 changes: 24 additions & 5 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,17 @@

Provides developer installation and usage information.

The minimum set of inputs to run a post-processing for composites is the result file(s) of an

Check failure on line 49 in doc/source/index.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] doc/source/index.rst#L49

[Google.OptionalPlurals] Don't use plurals in parentheses such as in 'file(s)'.
Raw output
{"message": "[Google.OptionalPlurals] Don't use plurals in parentheses such as in 'file(s)'.", "location": {"path": "doc/source/index.rst", "range": {"start": {"line": 49, "column": 81}}}, "severity": "ERROR"}
roosre marked this conversation as resolved.
Show resolved Hide resolved
MAPDL solution and a material file (matml) which was generated by Engineering Data.

Check failure on line 50 in doc/source/index.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] doc/source/index.rst#L50

[Vale.Spelling] Did you really mean 'matml'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'matml'?", "location": {"path": "doc/source/index.rst", "range": {"start": {"line": 50, "column": 37}}}, "severity": "ERROR"}
Lay-up files from ACP are optional and only required for some advanced operations. Refer to
:ref:`Limitations`.

roosre marked this conversation as resolved.
Show resolved Hide resolved
Key features
''''''''''''

Here are some key features of PyDPF Composites:

* Post-processing of layered shell and solid elements, whether they were preprocessed by ACP or not.
roosre marked this conversation as resolved.
Show resolved Hide resolved
* Failure criteria evaluation as shown in :ref:`Composite failure analysis <sphx_glr_examples_gallery_examples_001_failure_operator_example.py>`.
* A :class:`.SamplingPoint` class for extracting and visualizing a result over the entire thickness of a laminate as shown in
:ref:`Sampling point <sphx_glr_examples_gallery_examples_002_sampling_point_example.py>`.
Expand All @@ -63,15 +69,28 @@
* Postprocessing of homogeneous elements.


.. _limitations:

Limitations
'''''''''''
- Layered elements (section data) that have not been preprocessed with ACP are not supported.
For information on converting legacy models, see `Import of Legacy Mechanical APDL Composite Models`_
in the Ansys Help.
- Only the Mechanical APDL solver is supported.

- The following operators and features are only supported if the model was preprocessed with ACP
and if the corresponding lay-up definition file is passed to the :class:`.CompositeModel`:
roosre marked this conversation as resolved.
Show resolved Hide resolved
- The evaluation of the failure criteria for sandwich (:class:`FaceSheetWrinklingCriterion`, :class:`ShearCrimpingCriterion`)
roosre marked this conversation as resolved.
Show resolved Hide resolved
for solid elements. Layered shell elements are always supported.
- The computation of interlaminar normal stresses (s3) for layered shell elements.
Otherwise, s3 is zero. This also affects 3D failure criteria which use s3, such as Puck 3D.
This limitation does not affect (layered) solid elements.
- The support of variable materials and material fields. Without ACP, only the
temperature is considered for the evaluation of variable material properties.
- Global plies, ply-wise scoping, and ply-wise failure criteria. Layer-wise post-processing is

Check failure on line 86 in doc/source/index.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] doc/source/index.rst#L86

[Google.LyHyphens] ' ply-' doesn't need a hyphen.
Raw output
{"message": "[Google.LyHyphens] ' ply-' doesn't need a hyphen.", "location": {"path": "doc/source/index.rst", "range": {"start": {"line": 86, "column": 40}}}, "severity": "ERROR"}
roosre marked this conversation as resolved.
Show resolved Hide resolved
always supported thanks to the scripting
- Plotting results on the reference surface of a laminate.

Note: MAPDL models which have not been preprocessed with ACP can be converted. For more
roosre marked this conversation as resolved.
Show resolved Hide resolved
information, see `Import of Legacy Mechanical APDL Composite Models`_ in the Ansys Help.

.. _Ansys Workbench: https://download.ansys.com/Current%20Release
.. _Import of Legacy Mechanical APDL Composite Models: https://ansyshelp.ansys.com/account/secured?returnurl=/Views/Secured/corp/v231/en/acp_ug/acp_import_legacy_APDL_comp.html
.. _Import of Legacy Mechanical APDL Composite Models: https://ansyshelp.ansys.com/account/secured?returnurl=/Views/Secured/corp/v232/en/acp_ug/acp_import_legacy_APDL_comp.html
.. _Compatibility: https://dpf.docs.pyansys.com/version/stable/getting_started/compatibility.html
.. _Ansys DPF: https://dpf.docs.pyansys.com/version/stable/
6 changes: 3 additions & 3 deletions examples/008_assembly_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@
irf_field.plot()

# %%
# Plot IRF
# ~~~~~~~~
# Plot IRF on The Reference Surface
roosre marked this conversation as resolved.
Show resolved Hide resolved
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Plot the maximum IRF on the reference surface
if version_equal_or_later(server, "8.0"):
irf_field = output_all_elements.get_field(
Expand All @@ -72,7 +72,7 @@
# ~~~~~~~~~~~~~~~~~~~~~~~
# In the assembly, two composite definitions exist: one with a "shell" label
# and one with a "solid" label. For DPF Server versions earlier than 7.0,
# the layup properties must be queried with the correct composite definition label. The code
# the lay-up properties must be queried with the correct composite definition label. The code
# following gets element information for all layered elements.
# For DPF Server versions 7.0 and later, element information can be retrieved directly.

Expand Down
89 changes: 89 additions & 0 deletions examples/011_rst_workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"""
.. _rst_workflow_example:

Failure Analysis of an MAPDL (RST) Model
roosre marked this conversation as resolved.
Show resolved Hide resolved
----------------------------------------

The post-processing of a MAPDL (RST) model with layered elements which was not
preprocessed by ACP is shown by this example. The difference between the RST
roosre marked this conversation as resolved.
Show resolved Hide resolved
only and ACP based workflow is that `composite` of :class:`.ContinuousFiberCompositesFiles`
roosre marked this conversation as resolved.
Show resolved Hide resolved
is empty and so the section data are automatically loaded from the RST file.
roosre marked this conversation as resolved.
Show resolved Hide resolved

The engineering data file (XML or ENGD) with the material properties is needed anyway.
Otherwise, the material properties cannot be mapped. It is recommended
to create it before solving the model. The engineering data file can be either generated with Ansys Workbench
or ACP (Ansys Composite PrePost) standalone. Important: The material UUIDs in the engineering data file
must be identical to the UUIDs in the Mechanical APDL (RST file).
The material UUID can be set in Mechanical APDL with the command ``MP,UVID,<material index>,<value>``.
roosre marked this conversation as resolved.
Show resolved Hide resolved

This workflow is supported since version 2024 R2 (DPF Server version 8.0). A few advanced features are
not supported with the RST onl workflow. Refer to Section :ref:`limitations` for details.
roosre marked this conversation as resolved.
Show resolved Hide resolved
"""
# %%
# Set up analysis
# ~~~~~~~~~~~~~~~
# Setting up the analysis consists of loading Ansys libraries, connecting to the
# DPF server, and retrieving the example files.
#
# Load Ansys libraries.

from ansys.dpf.composites.composite_model import CompositeModel, CompositeScope
from ansys.dpf.composites.constants import FailureOutput
from ansys.dpf.composites.example_helper import get_continuous_fiber_example_files
from ansys.dpf.composites.failure_criteria import (
CombinedFailureCriterion,
CoreFailureCriterion,
MaxStrainCriterion,
MaxStressCriterion,
VonMisesCriterion,
FaceSheetWrinklingCriterion,
ShearCrimpingCriterion,
)
from ansys.dpf.composites.server_helpers import connect_to_or_start_server

# %%
# Start a DPF server and copy the example files into the current working directory.
server = connect_to_or_start_server()

# %%
# Get input files (RST and material.engd but skip the ACP layup file)
roosre marked this conversation as resolved.
Show resolved Hide resolved
composite_files_on_server = get_continuous_fiber_example_files(server, "shell", True)
roosre marked this conversation as resolved.
Show resolved Hide resolved
print(composite_files_on_server)

# %%
# Configure combined failure criterion
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Configure the combined failure criterion.

combined_fc = CombinedFailureCriterion(
name="failure of all materials",
failure_criteria=[
MaxStrainCriterion(),
MaxStressCriterion(),
CoreFailureCriterion(),
VonMisesCriterion(vme=True, vms=False),
FaceSheetWrinklingCriterion(),
],
)

# %%
# Set up model and evaluate failures
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Set up the composite model.

composite_model = CompositeModel(composite_files_on_server, server)

# %%
# Evaluate failures for the entire model
roosre marked this conversation as resolved.
Show resolved Hide resolved
output_all_elements = composite_model.evaluate_failure_criteria(
combined_criterion=combined_fc,
)
irf_field = output_all_elements.get_field({"failure_label": FailureOutput.FAILURE_VALUE})
irf_field.plot()

# %%
# Create and plot a sampling point
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sampling_point = composite_model.get_sampling_point(combined_criterion=combined_fc, element_id=2)
sampling_plot = sampling_point.get_result_plots(core_scale_factor=0.1)
sampling_plot.figure.show()
45 changes: 37 additions & 8 deletions src/ansys/dpf/composites/_composite_model_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
ElementInfo,
LayerProperty,
LayupPropertiesProvider,
LayupModelModelContextType,
add_layup_info_to_mesh,
get_element_info_provider,
)
from .layup_info._reference_surface import (
_get_map_to_reference_surface_operator,
_get_reference_surface_and_mapping_field,
)
from .layup_info._layup_info import _get_layup_model_context
from .layup_info.material_operators import MaterialOperators, get_material_operators
from .layup_info.material_properties import MaterialProperty, get_constant_property_dict
from .result_definition import FailureMeasureEnum
Expand Down Expand Up @@ -174,9 +176,18 @@ def __init__(
data_sources=self.data_sources,
material_operators=self.material_operators,
unit_system=self._unit_system,
rst_stream_provider=self._get_rst_streams_provider()
)

# self._layup_provider.outputs.layup_model_context_type.get_data() does not work because
# int32 is not supported in the Python API. See bug 946754.
# 218 is the pin of LayupModelContext
if version_equal_or_later(self._server, "8.0"):
self.layup_model_type = LayupModelModelContextType(_get_layup_model_context(self._layup_provider))
else:
self.layup_model_type = LayupModelModelContextType.ACP if len(composite_files.composite) > 0 else LayupModelModelContextType.NOT_AVAILABLE

if self._supports_reference_surface_operators():
self._reference_surface_and_mapping_field = _get_reference_surface_and_mapping_field(
data_sources=self.data_sources.composite, unit_system=self._unit_system
)
Expand All @@ -189,6 +200,7 @@ def __init__(
self._element_info_provider = get_element_info_provider(
mesh=self.get_mesh(),
stream_provider_or_data_source=self._get_rst_streams_provider(),
material_provider=self.material_operators.material_provider,
)
self._layup_properties_provider = LayupPropertiesProvider(
layup_provider=self._layup_provider, mesh=self.get_mesh()
Expand Down Expand Up @@ -246,8 +258,8 @@ def material_names(self) -> dict[str, int]:
material_ids = string_field.scoping.ids

names = {}
for mat_id in material_ids:
names[string_field.data[string_field.scoping.index(mat_id)]] = mat_id
for dpf_mat_id in material_ids:
names[string_field.data[string_field.scoping.index(dpf_mat_id)]] = dpf_mat_id

return names

Expand Down Expand Up @@ -332,8 +344,6 @@ def evaluate_failure_criteria(
# is irrelevant for cases without a ply scope, we set it to False here.
write_data_for_full_element_scope = False

has_layup_provider = len(self._composite_files.composite) > 0

# configure primary scoping
scope_config = dpf.DataTree()
if time_in:
Expand All @@ -355,7 +365,9 @@ def evaluate_failure_criteria(
chunking_generator = dpf.Operator("composite::scope_generator")
chunking_generator.inputs.stream_provider(self._get_rst_streams_provider())
chunking_generator.inputs.data_tree(chunking_data_tree)
chunking_generator.inputs.data_sources(self.data_sources.composite)
if self.data_sources.composite:
chunking_generator.inputs.data_sources(self.data_sources.composite)

if element_scope_in:
element_scope = dpf.Scoping(location="elemental")
element_scope.ids = element_scope_in
Expand Down Expand Up @@ -396,7 +408,12 @@ def evaluate_failure_criteria(
self._get_rst_streams_provider()
)
evaluate_failure_criterion_per_scope_op.inputs.mesh(self.get_mesh())
evaluate_failure_criterion_per_scope_op.inputs.has_layup_provider(has_layup_provider)
if version_equal_or_later(self._server, "8.0"):
evaluate_failure_criterion_per_scope_op.inputs.layup_model_context_type(self.layup_model_type.value)
else:
evaluate_failure_criterion_per_scope_op.inputs.has_layup_provider(
self.layup_model_type != LayupModelModelContextType.NOT_AVAILABLE
)
evaluate_failure_criterion_per_scope_op.inputs.section_data_container(
self._layup_provider.outputs.section_data_container
)
Expand All @@ -421,7 +438,8 @@ def evaluate_failure_criteria(
self.material_operators.material_support_provider.outputs
)

if has_layup_provider and write_data_for_full_element_scope:
if (self.layup_model_type != LayupModelModelContextType.NOT_AVAILABLE and
write_data_for_full_element_scope):
add_default_data_op = dpf.Operator("composite::add_default_data")
add_default_data_op.inputs.requested_element_scoping(chunking_generator.outputs)
add_default_data_op.inputs.time_id(
Expand Down Expand Up @@ -458,7 +476,7 @@ def evaluate_failure_criteria(
"No output is generated! Please check the scope (element and ply ids)."
roosre marked this conversation as resolved.
Show resolved Hide resolved
)

if version_equal_or_later(self._server, "8.0"):
if self._supports_reference_surface_operators():
self._map_to_reference_surface_operator.inputs.min_container(
min_merger.outputs.merged_fields_container()
)
Expand Down Expand Up @@ -739,3 +757,14 @@ def _first_composite_definition_label_if_only_one(self) -> str:
f"Multiple composite definition keys exist: {self.composite_definition_labels}. "
f"Specify a key explicitly."
)

# Whether the reference surface operators are available or supported by the server
def _supports_reference_surface_operators(self):
if not version_equal_or_later(self._server, "8.0"):
return False

if (self.layup_model_type == LayupModelModelContextType.ACP or
self.layup_model_type == LayupModelModelContextType.MIXED):
return True

return False
Loading
Loading