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 8 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
10 changes: 7 additions & 3 deletions src/ansys/dpf/composites/_composite_model_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,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()
)

if version_equal_or_later(self._server, "8.0"):
Expand All @@ -189,6 +190,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 +248,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 @@ -355,7 +357,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
110 changes: 72 additions & 38 deletions src/ansys/dpf/composites/_indexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,15 @@ class FieldIndexerNoDataPointer:

def __init__(self, field: Field):
"""Create indexer and get data."""
index_by_id = setup_index_by_id(field.scoping)
self._indices = index_by_id.mapping
self._max_id = index_by_id.max_id
self._data: NDArray[np.double] = np.array(field.data, dtype=np.double)
if field.scoping.size > 0:
index_by_id = setup_index_by_id(field.scoping)
self._indices = index_by_id.mapping
self._max_id = index_by_id.max_id
self._data: NDArray[np.double] = np.array(field.data, dtype=np.double)
else:
self._indices = np.array([], dtype=np.int64)
self._max_id = 0
self._data = np.array([], dtype=np.double)

def by_id(self, entity_id: int) -> Optional[np.double]:
"""Get index by id.
roosre marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -110,9 +115,15 @@ class PropertyFieldIndexerNoDataPointerNoBoundsCheck:

def __init__(self, field: PropertyField):
"""Create indexer and get data."""
index_by_id = setup_index_by_id(field.scoping)
self._indices = index_by_id.mapping
self._data: NDArray[np.int64] = np.array(field.data, dtype=np.int64)
if field.scoping.size > 0:
index_by_id = setup_index_by_id(field.scoping)
self._indices = index_by_id.mapping
self._data: NDArray[np.int64] = np.array(field.data, dtype=np.int64)
self._max_id = index_by_id.max_id
else:
self._indices = np.array([], dtype=np.int64)
self._data = np.array([], dtype=np.int64)
self._max_id = 0

def by_id(self, entity_id: int) -> Optional[np.int64]:
"""Get index by id.
roosre marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -121,24 +132,34 @@ def by_id(self, entity_id: int) -> Optional[np.int64]:
----------
entity_id
"""
return cast(np.int64, self._data[self._indices[entity_id]])
if entity_id > self._max_id:
return None
else:
return cast(np.int64, self._data[self._indices[entity_id]])


class PropertyFieldIndexerWithDataPointer:
"""Indexer for a property field with data pointer."""

def __init__(self, field: PropertyField):
"""Create indexer and get data."""
index_by_id = setup_index_by_id(field.scoping)
self._indices = index_by_id.mapping
self._max_id = index_by_id.max_id

self._data: NDArray[np.int64] = np.array(field.data, dtype=np.int64)
self._n_components = field.component_count

self._data_pointer: NDArray[np.int64] = np.append(
field._data_pointer, len(self._data) * self._n_components
)
if field.scoping.size > 0:
index_by_id = setup_index_by_id(field.scoping)
self._indices = index_by_id.mapping
self._max_id = index_by_id.max_id

self._data: NDArray[np.int64] = np.array(field.data, dtype=np.int64)
self._n_components = field.component_count

self._data_pointer: NDArray[np.int64] = np.append(
field._data_pointer, len(self._data) * self._n_components
)
else:
self._max_id = 0
self._indices = np.array([], dtype=np.int64)
self._data = np.array([], dtype=np.int64)
self._n_components = 0
self._data_pointer = np.array([], dtype=np.int64)

def by_id(self, entity_id: int) -> Optional[NDArray[np.int64]]:
"""Get index by id.
roosre marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -166,18 +187,26 @@ def by_id(self, entity_id: int) -> Optional[NDArray[np.int64]]:
class FieldIndexerWithDataPointer:
"""Indexer for a dpf field with data pointer."""
roosre marked this conversation as resolved.
Show resolved Hide resolved


def __init__(self, field: Field):
"""Create indexer and get data."""
index_by_id = setup_index_by_id(field.scoping)
self._indices = index_by_id.mapping
self._max_id = index_by_id.max_id

self._data: NDArray[np.double] = np.array(field.data, dtype=np.double)
self._n_components = field.component_count

self._data_pointer: NDArray[np.int64] = np.append(
field._data_pointer, len(self._data) * self._n_components
)
if field.scoping.size > 0:
index_by_id = setup_index_by_id(field.scoping)
self._indices = index_by_id.mapping
self._max_id = index_by_id.max_id

self._data: NDArray[np.double] = np.array(field.data, dtype=np.double)
self._n_components = field.component_count

self._data_pointer: NDArray[np.int64] = np.append(
field._data_pointer, len(self._data) * self._n_components
)
else:
self._max_id = 0
self._indices = np.array([], dtype=np.int64)
self._data = np.array([], dtype=np.double)
self._n_components = 0
self._data_pointer = np.array([], dtype=np.int64)

def by_id(self, entity_id: int) -> Optional[NDArray[np.double]]:
"""Get index by id.
roosre marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -207,16 +236,21 @@ class PropertyFieldIndexerWithDataPointerNoBoundsCheck:

def __init__(self, field: PropertyField):
"""Create indexer and get data."""
index_by_id = setup_index_by_id(field.scoping)
self._indices = index_by_id.mapping

self._data: NDArray[np.int64] = np.array(field.data, dtype=np.int64)

self._n_components = field.component_count

self._data_pointer: NDArray[np.int64] = np.append(
field._data_pointer, len(self._data) * self._n_components
)
if field.scoping.size > 0:
index_by_id = setup_index_by_id(field.scoping)
self._indices = index_by_id.mapping

self._data: NDArray[np.int64] = np.array(field.data, dtype=np.int64)
self._n_components = field.component_count

self._data_pointer: NDArray[np.int64] = np.append(
field._data_pointer, len(self._data) * self._n_components
)
else:
self._indices = np.array([], dtype=np.int64)
self._data = np.array([], dtype=np.int64)
self._n_components = 0
self._data_pointer = np.array([], dtype=np.int64)

def by_id(self, entity_id: int) -> Optional[NDArray[np.int64]]:
"""Get index by id.
roosre marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
10 changes: 7 additions & 3 deletions src/ansys/dpf/composites/data_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,14 @@ def _get_rst_list(value: Union[list[_PATH], _PATH]) -> list[_PATH]:
return value # type: ignore


# roosre June 2023: todo add deprecation warning where composite definition label is used
@dataclass(frozen=True)
class CompositeDataSources:
"""Provides data sources related to the composite lay-up.

Parameters
----------
rst:
Result file. Currently only RST (MAPDL) is supported.

material_support:
roosre marked this conversation as resolved.
Show resolved Hide resolved
NOTE: The 'material_support' is explicitly listed since it is currently not
roosre marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -165,6 +165,7 @@ class CompositeDataSources:
material support from the first RST file. This is a workaround until the
support for distributed RST is added.
engineering_data:
roosre marked this conversation as resolved.
Show resolved Hide resolved
File with the material properties.

old_composite_sources:
roosre marked this conversation as resolved.
Show resolved Hide resolved
This member is used to support assemblies in combination with the old
roosre marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -175,7 +176,7 @@ class CompositeDataSources:

rst: DataSources
material_support: DataSources
composite: DataSources
composite: Optional[DataSources]
engineering_data: DataSources

old_composite_sources: dict[str, DataSources]
Expand Down Expand Up @@ -542,7 +543,6 @@ def get_composites_data_sources(
old_composite_data_sources = {}

for key, composite_files in continuous_composite_files.composite.items():
old_datasource = DataSources()
if set_part_key:
composite_data_source.add_file_path_for_specified_result(
composite_files.definition, _LAYUPFILE_INDEX_KEY, key
Expand All @@ -567,6 +567,10 @@ def get_composites_data_sources(

old_composite_data_sources[key] = old_datasource

# Reset composite data source if no composite files are provided because a data source cannot be empty
if len(continuous_composite_files.composite) == 0:
composite_data_source = None

return CompositeDataSources(
rst=rst_data_source,
material_support=material_support_data_source,
Expand Down
30 changes: 24 additions & 6 deletions src/ansys/dpf/composites/layup_info/_add_layup_info_to_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@

def _get_composite_data_sources_for_layup_provider(
data_sources: CompositeDataSources, composite_definition_label: Optional[str] = None
) -> DataSources:
) -> Optional[DataSources]:
"""
Prepare DataSources of composite for the DPF server.
roosre marked this conversation as resolved.
Show resolved Hide resolved

Ensure that DataSources object is compatible with the version of the layup provider.
roosre marked this conversation as resolved.
Show resolved Hide resolved
"""

if data_sources.composite is None:
return None

# import is here because of circular dependencies
from ..server_helpers import version_older_than

Expand Down Expand Up @@ -50,6 +54,7 @@ def add_layup_info_to_mesh(
mesh: MeshedRegion,
unit_system: Optional[UnitSystemProvider] = None,
composite_definition_label: Optional[str] = None,
rst_stream_provider: Optional[Operator] = None,
) -> Operator:
"""Add lay-up information to the mesh.

Expand All @@ -71,21 +76,28 @@ def add_layup_info_to_mesh(
dictionary key in the :attr:`.ContinuousFiberCompositesFiles.composite`
attribute. This parameter is only required for assemblies.
See the note about assemblies in the description for the :class:`.CompositeModel` class.
rst_stream_provider:
roosre marked this conversation as resolved.
Show resolved Hide resolved
Pass RST stream to load section data directly from the RST file. Support with DPF 2024R2
(8.0) and later.
roosre marked this conversation as resolved.
Show resolved Hide resolved

Returns
-------
:
roosre marked this conversation as resolved.
Show resolved Hide resolved
Lay-up provider operator.
"""
composite_data_sources = _get_composite_data_sources_for_layup_provider(
data_sources, composite_definition_label
)

# Set up the lay-up provider.
# Reads the composite definition file and enriches the mesh
# with the composite lay-up information.
layup_provider = Operator("composite::layup_provider_operator")
layup_provider.inputs.mesh(mesh)
layup_provider.inputs.data_sources(composite_data_sources)

composite_data_sources = _get_composite_data_sources_for_layup_provider(
roosre marked this conversation as resolved.
Show resolved Hide resolved
data_sources, composite_definition_label
)

if composite_data_sources:
layup_provider.inputs.data_sources(composite_data_sources)

layup_provider.inputs.abstract_field_support(
material_operators.material_support_provider.outputs.abstract_field_support
)
Expand All @@ -101,6 +113,12 @@ def add_layup_info_to_mesh(
unit_system = material_operators.result_info_provider

layup_provider.inputs.unit_system(unit_system)

if rst_stream_provider:
roosre marked this conversation as resolved.
Show resolved Hide resolved
from ..server_helpers import version_equal_or_later
if version_equal_or_later(layup_provider._server, "8.0"):
layup_provider.inputs.rst_stream(rst_stream_provider)

layup_provider.run()

return layup_provider
Loading
Loading