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

Doc/cyclic symmetry #517

Merged
merged 41 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
41 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
2652dc0
Merge branch 'main' of https://github.com/ansys/pydpf-composites
roosre Dec 12, 2023
3849e5d
Merge branch 'main' of https://github.com/ansys/pydpf-composites
roosre Dec 15, 2023
a306ff8
Merge branch 'main' of https://github.com/ansys/pydpf-composites
roosre Sep 9, 2024
61f012a
Merge branch 'main' of https://github.com/ansys/pydpf-composites
roosre Sep 9, 2024
93a4c4d
draft of a cyclic symmetry example
roosre Sep 10, 2024
8feffeb
run style check
roosre Sep 10, 2024
e912b0c
run style checks
roosre Sep 12, 2024
cf36704
cosmetic changes
roosre Sep 12, 2024
ea32914
cosmetic changes
roosre Sep 12, 2024
04dfcf5
add get_rst_streams_provider to CompositeModelImpl2023R2
roosre Sep 12, 2024
248da9d
polish examples/014_cyclic_symmetry.py
roosre Sep 13, 2024
77f2c80
cosmetic changes
roosre Sep 13, 2024
defb04f
revert temporary change
roosre Sep 13, 2024
07d3688
rename file
roosre Sep 13, 2024
928d0f2
cosmetic changes
roosre Sep 13, 2024
537266f
add link to DPF Core
roosre Sep 13, 2024
48fdb01
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
393b270
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
a607935
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
0625080
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
cf900a1
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
7c79795
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
48e661c
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
98f9c50
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
2c27077
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
15df3c1
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
670b0ed
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
4edd23e
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
817b77b
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
9315769
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 13, 2024
5324306
run style checks after doc update
roosre Sep 16, 2024
f88c98d
Update examples/014_cyclic_symmetry_example.py
nshum4 Sep 16, 2024
6cbebb6
Update examples/014_cyclic_symmetry_example.py
roosre Sep 16, 2024
5408d9e
document limitation about expaned cyclic symmetry models.
roosre Sep 17, 2024
d724ead
Merge branch 'doc/cyclic_symmetry' of https://github.com/ansys/pydpf-…
roosre Sep 17, 2024
5474d85
Merge branch 'main' into doc/cyclic_symmetry
roosre Sep 18, 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
160 changes: 160 additions & 0 deletions examples/014_cyclic_symmetry_example.py
roosre marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
.. _cyclic_symmetry_example:

Cyclic symmetry
---------------

This example shows how to postprocess a cyclic symmetry analysis.
The initial (original) sector can be postprocessed with the same tools
as a standard analysis. This is demonstrated by running a failure analysis,
nshum4 marked this conversation as resolved.
Show resolved Hide resolved
extracting ply-wise stresses and the implementation of a custom
nshum4 marked this conversation as resolved.
Show resolved Hide resolved
failure criterion.
roosre marked this conversation as resolved.
Show resolved Hide resolved

The postprocessing of expanded sectors is not yet supported.
roosre marked this conversation as resolved.
Show resolved Hide resolved
"""

# %%
# Set up analysis
# ~~~~~~~~~~~~~~~
# Setting up the analysis consists of loading the required modules, connecting to the
# DPF server, and retrieving the example files.
#
# Load Ansys libraries and helper functions.
import ansys.dpf.core as dpf

from ansys.dpf.composites.composite_model import CompositeModel
from ansys.dpf.composites.constants import FailureOutput, Sym3x3TensorComponent
from ansys.dpf.composites.example_helper import get_continuous_fiber_example_files
from ansys.dpf.composites.failure_criteria import CombinedFailureCriterion, MaxStressCriterion
from ansys.dpf.composites.layup_info import get_all_analysis_ply_names
from ansys.dpf.composites.layup_info.material_properties import MaterialProperty
from ansys.dpf.composites.ply_wise_data import SpotReductionStrategy, get_ply_wise_data
from ansys.dpf.composites.select_indices import get_selected_indices
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()
composite_files = get_continuous_fiber_example_files(server, "cyclic_symmetry")

# %%
# Create a composite model.
composite_model = CompositeModel(composite_files, server)

# %%
# Evaluate a combined failure criterion.
combined_failure_criterion = CombinedFailureCriterion(failure_criteria=[MaxStressCriterion()])
failure_result = composite_model.evaluate_failure_criteria(combined_failure_criterion)

# %%
# Plot the failure results.
irf_field = failure_result.get_field({"failure_label": FailureOutput.FAILURE_VALUE})
irf_field.plot()

# %%
# Plot ply-wise stresses
# ~~~~~~~~~~~~~~~~~~~~~~
# All functions in PyDPF Composites can be used to
# postprocess the initial (original) sector.

rst_stream = composite_model.core_model.metadata.streams_provider
stress_operator = dpf.operators.result.stress()
stress_operator.inputs.streams_container.connect(rst_stream)
stress_operator.inputs.bool_rotate_to_global(False)
stress_container = stress_operator.outputs.fields_container()

all_ply_names = get_all_analysis_ply_names(composite_model.get_mesh())
all_ply_names

component_s11 = Sym3x3TensorComponent.TENSOR11
stress_field = stress_container[0]
elemental_values = get_ply_wise_data(
field=stress_field,
ply_name="P3L1__ModelingPly.1",
mesh=composite_model.get_mesh(),
component=component_s11,
spot_reduction_strategy=SpotReductionStrategy.MAX,
requested_location=dpf.locations.elemental,
)
composite_model.get_mesh().plot(elemental_values)

# %%
# Custom failure criterion
# ~~~~~~~~~~~~~~~~~~~~~~~~
# The following code block shows how to implement a custom failure criterion.
# It computes the inverse reserve factor for each element with respect to
# fiber failure. The criterion distinguishes between tension and compression.

# Prepare dict with the material properties
nshum4 marked this conversation as resolved.
Show resolved Hide resolved
property_xt = MaterialProperty.Stress_Limits_Xt
property_xc = MaterialProperty.Stress_Limits_Xc
property_dict = composite_model.get_constant_property_dict([property_xt, property_xc])

result_field = dpf.field.Field(location=dpf.locations.elemental, nature=dpf.natures.scalar)
with result_field.as_local_field() as local_result_field:
# Process only the layered elements
for element_id in composite_model.get_all_layered_element_ids():
element_info = composite_model.get_element_info(element_id)
element_irf_max = 0.0
stress_data = stress_field.get_entity_data_by_id(element_id)
for layer_index, dpf_material_id in enumerate(element_info.dpf_material_ids):
xt = property_dict[dpf_material_id][property_xt]
xc = property_dict[dpf_material_id][property_xc]
selected_indices = get_selected_indices(element_info, layers=[layer_index])
# Maximum of fiber failure in tension and compression
layer_stress_values = stress_data[selected_indices][:, component_s11]
max_s11 = max(layer_stress_values)
min_s11 = min(layer_stress_values)
if xt > 0 and max_s11 > 0:
element_irf_max = max(max_s11 / xt, element_irf_max)
if xc < 0 and min_s11 < 0:
element_irf_max = max(min_s11 / xc, element_irf_max)

local_result_field.append([element_irf_max], element_id)

composite_model.get_mesh().plot(result_field)

# %%
# Plot deformations on the expanded model
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# You can expand the deformations of the cyclic symmetry model as shown below. The same expansion is possible for strains and stresses. For more information, see `Ansys DPF`_.
nshum4 marked this conversation as resolved.
Show resolved Hide resolved
# deformations of the cyclic symmetry model. The same can be done
nshum4 marked this conversation as resolved.
Show resolved Hide resolved
# for strains and stresses. See `Ansys DPF`_ for more details.
nshum4 marked this conversation as resolved.
Show resolved Hide resolved
#
# .. _Ansys DPF: https://dpf.docs.pyansys.com/version/stable/

# Get the displacements and expand them
symmetry_option = 2 # fully expand the model
u_cyc = composite_model.core_model.results.displacement()
u_cyc.inputs.read_cyclic(symmetry_option)
# expand the displacements
deformations = u_cyc.outputs.fields_container()[0]

# Get and expand the mesh
mesh_provider = composite_model.core_model.metadata.mesh_provider
mesh_provider.inputs.read_cyclic(symmetry_option)
mesh = mesh_provider.outputs.mesh()
# Plot the expanded deformations
mesh.plot(deformations)
15 changes: 8 additions & 7 deletions src/ansys/dpf/composites/_composite_model_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ 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(),
rst_stream_provider=self.get_rst_streams_provider(),
)

# self._layup_provider.outputs.layup_model_context_type.get_data() does not work because
Expand Down Expand Up @@ -154,7 +154,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(),
stream_provider_or_data_source=self.get_rst_streams_provider(),
material_provider=self.material_operators.material_provider,
)
self._layup_properties_provider = LayupPropertiesProvider(
Expand Down Expand Up @@ -370,7 +370,7 @@ def evaluate_failure_criteria(
chunking_data_tree.add({"named_selections": ns_in})

chunking_generator = dpf.Operator("composite::scope_generator")
chunking_generator.inputs.stream_provider(self._get_rst_streams_provider())
chunking_generator.inputs.stream_provider(self.get_rst_streams_provider())
chunking_generator.inputs.data_tree(chunking_data_tree)
if self.data_sources.composite:
chunking_generator.inputs.data_sources(self.data_sources.composite)
Expand Down Expand Up @@ -412,7 +412,7 @@ def evaluate_failure_criteria(
self.material_operators.material_provider.outputs
)
evaluate_failure_criterion_per_scope_op.inputs.stream_provider(
self._get_rst_streams_provider()
self.get_rst_streams_provider()
)
evaluate_failure_criterion_per_scope_op.inputs.mesh(self.get_mesh())
if version_equal_or_later(self._server, "8.0"):
Expand Down Expand Up @@ -555,7 +555,7 @@ def get_sampling_point(
self._material_operators,
self.get_mesh(),
self._layup_provider,
self._get_rst_streams_provider(),
self.get_rst_streams_provider(),
self._data_sources.rst,
self._unit_system,
time_in,
Expand Down Expand Up @@ -688,7 +688,7 @@ def get_constant_property_dict(
return get_constant_property_dict(
material_properties=material_properties,
materials_provider=self.material_operators.material_provider,
data_source_or_streams_provider=self._get_rst_streams_provider(),
data_source_or_streams_provider=self.get_rst_streams_provider(),
mesh=self.get_mesh(),
)

Expand Down Expand Up @@ -766,7 +766,8 @@ def get_all_layered_element_ids_for_composite_definition_label(
)
return self.get_all_layered_element_ids()

def _get_rst_streams_provider(self) -> Operator:
def get_rst_streams_provider(self) -> Operator:
"""Get the streams provider of the loaded result file."""
return self._core_model.metadata.streams_provider

def _first_composite_definition_label_if_only_one(self) -> str:
Expand Down
4 changes: 4 additions & 0 deletions src/ansys/dpf/composites/_composite_model_impl_2023r2.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,3 +644,7 @@ 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."
)

def get_rst_streams_provider(self) -> Operator:
"""Get the streams provider of the loaded result file."""
return self._core_model.metadata.streams_provider
4 changes: 4 additions & 0 deletions src/ansys/dpf/composites/composite_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ def get_mesh(self, composite_definition_label: Optional[str] = None) -> MeshedRe
"""
return self._implementation.get_mesh(composite_definition_label)

def get_rst_streams_provider(self) -> Operator:
"""Get the streams provider of the loaded result file."""
return self._implementation.get_rst_streams_provider()

def get_layup_operator(self, composite_definition_label: Optional[str] = None) -> Operator:
"""Get the lay-up operator.

Expand Down
12 changes: 11 additions & 1 deletion src/ansys/dpf/composites/example_helper/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@


# Example URL to run the examples locally
# EXAMPLE_REPO = "file:////D:/Development/pyansys-example-data/pydpf-composites/"
# EXAMPLE_REPO = "file:////D:/dev/pyansys-example-data/pydpf-composites/"


@dataclass
Expand Down Expand Up @@ -165,6 +165,16 @@ class _ShortFiberExampleLocation:
},
),
),
"cyclic_symmetry": _ContinuousFiberExampleLocation(
directory="cyclic_symmetry",
files=_ContinuousFiberCompositesExampleFilenames(
rst=["file.rst"],
engineering_data="MatML.xml",
composite={
"solid": _ContinuousFiberCompositeFiles(definition="ACPSolidModel_SM.h5"),
},
),
),
}

_short_fiber_examples: dict[str, _ShortFiberExampleLocation] = {
Expand Down
Loading