-
Notifications
You must be signed in to change notification settings - Fork 23
doc(tuto): DPF collections tutorial #2742
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
base: main
Are you sure you want to change the base?
Changes from all commits
1a6cfef
e4de9ef
d5d9d45
20b2ca7
cd4eac9
acc44d6
aa8797e
d0bd71d
726718f
41fd4a4
6c36bdb
faba694
75d0940
3d4c48b
77e241a
41389ab
6aef712
61d2565
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,311 @@ | ||||||||||||||||||||||||||
| .. _ref_tutorials_collections: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| =============== | ||||||||||||||||||||||||||
| DPF Collections | ||||||||||||||||||||||||||
| =============== | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| .. include:: ../../links_and_refs.rst | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| This tutorial demonstrates how to create and work with some DPF collections: FieldsContainer, MeshesContainer and ScopingsContainer. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| DPF collections are homogeneous groups of labeled raw data storage structures that allow you to organize and manipulate related data efficiently. Collections are essential for handling multiple time steps, frequency sets, or other labeled datasets in your analysis workflows. | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean by "homogeneous groups"? |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| :jupyter-download-script:`Download tutorial as Python script<collections>` | ||||||||||||||||||||||||||
| :jupyter-download-notebook:`Download tutorial as Jupyter notebook<collections>` | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Introduction to Collections | ||||||||||||||||||||||||||
| --------------------------- | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Collections in DPF serve as containers that group related objects with labels. The main collection types are: | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We did this same intro with other words just before this. I prefer this formulation because it is more straightforward. (but again I would just avoid using the term "label" as a generic word here because "Label" is a DPF concept ) |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - |FieldsContainer|: A collection of |Field| objects, typically representing results over multiple time steps or frequency sets | ||||||||||||||||||||||||||
| - |MeshesContainer|: A collection of |MeshedRegion| objects for different configurations or time steps | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The term "configurations" her can be misunderstood as it is also a term in the DPF vocabulary. |
||||||||||||||||||||||||||
| - |ScopingsContainer|: A collection of |Scoping| objects for organizing entity selections | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Each collection provides methods to: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - Add, retrieve, and iterate over contained objects | ||||||||||||||||||||||||||
| - Access objects by label (time, frequency, set ID, and so on) | ||||||||||||||||||||||||||
| - Perform operations across all contained objects | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Collections are widely used in DPF workflows to provide vectorized data to operators, | ||||||||||||||||||||||||||
| allowing you to process the data in bulk or to process it in parallel whenever possible. | ||||||||||||||||||||||||||
|
Comment on lines
+31
to
+32
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would avoid terms that do not express certainty when defining something. Here the "Collections are widely used in DPF..." : this is the only use? this is the main use ? what are the other use cases? |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Set up the Analysis | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The analysis ? I thinks this can lead to misunderstandings |
||||||||||||||||||||||||||
| ------------------- | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| First, import the required modules and load a transient analysis result file that contains multiple time steps. | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that we should have an explanation about why we are starting by this or what are the global steps we are going to work on the tutorial (maybe this is something that lacks in the other tutorials too) |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| .. jupyter-execute:: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Import the ansys.dpf.core module | ||||||||||||||||||||||||||
| import ansys.dpf.core as dpf | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Import the examples module | ||||||||||||||||||||||||||
| from ansys.dpf.core import examples | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Load a transient analysis with multiple time steps | ||||||||||||||||||||||||||
| result_file_path = examples.find_msup_transient() | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Create a DataSources object | ||||||||||||||||||||||||||
| data_sources = dpf.DataSources(result_path=result_file_path) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Create a Model from the data sources | ||||||||||||||||||||||||||
| model = dpf.Model(data_sources=data_sources) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Display basic model information | ||||||||||||||||||||||||||
| print(model) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Working with FieldsContainer | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As we repeat this section for the different collection types and to avoid a giant tutorial page, I would have them in tabs. |
||||||||||||||||||||||||||
| ----------------------------- | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before working with Fields Containers we could show how a FieldsContainer is ? Maybe on the introduction to Collections |
||||||||||||||||||||||||||
| A |FieldsContainer| is the most commonly used collection in DPF. It stores multiple |Field| objects, each associated with a label such as time step or frequency. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Extract Results into a FieldsContainer | ||||||||||||||||||||||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Extract displacement results for all time steps, which will automatically create a |FieldsContainer|. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| .. jupyter-execute:: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Get displacement results for all time steps | ||||||||||||||||||||||||||
| displacement_fc = model.results.displacement.on_all_time_freqs.eval() | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Display FieldsContainer information | ||||||||||||||||||||||||||
| print(displacement_fc) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Access Individual Fields in the Container | ||||||||||||||||||||||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| You can access individual fields by their label or index. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| .. jupyter-execute:: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Access field by index (first time step) | ||||||||||||||||||||||||||
| first_field = displacement_fc[0] | ||||||||||||||||||||||||||
| print(f"First field info:") | ||||||||||||||||||||||||||
| print(first_field) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Access field by label (specific time step) | ||||||||||||||||||||||||||
| second_time_field = displacement_fc.get_field({"time": 2}) | ||||||||||||||||||||||||||
| # Equivalent to: | ||||||||||||||||||||||||||
| second_time_field = displacement_fc.get_field_by_time_id(2) | ||||||||||||||||||||||||||
| print(f"\nSecond time step field:") | ||||||||||||||||||||||||||
| print(second_time_field) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Create a Custom FieldsContainer | ||||||||||||||||||||||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| You can create your own |FieldsContainer| and add fields with custom labels. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| .. jupyter-execute:: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Create an empty FieldsContainer | ||||||||||||||||||||||||||
| custom_fc = dpf.FieldsContainer() | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Set up labels for the container | ||||||||||||||||||||||||||
| custom_fc.labels = ["time", "zone"] | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Create sample fields for different time steps and zones | ||||||||||||||||||||||||||
| for time_step in [1, 2]: | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe as we are in a basic tutorial we should avoid loops. They are less explicit on what we want to build. As if I'm working on this tutorial I would prefer something more visual/ straightforward |
||||||||||||||||||||||||||
| for zone in [1, 2]: | ||||||||||||||||||||||||||
| # Create a simple field with sample data | ||||||||||||||||||||||||||
| field = dpf.Field(location=dpf.locations.nodal, nature=dpf.natures.scalar) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Add some sample nodes and data | ||||||||||||||||||||||||||
| field.scoping.ids = [1, 2, 3, 4, 5] | ||||||||||||||||||||||||||
| field.data = [float(time_step * zone * i) for i in range(1, 6)] | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Add field to container with labels | ||||||||||||||||||||||||||
| custom_fc.add_field({"time": time_step, "zone": zone}, field) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Display the custom FieldsContainer | ||||||||||||||||||||||||||
| print(custom_fc) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Working with ScopingsContainer | ||||||||||||||||||||||||||
| ------------------------------ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| A |ScopingsContainer| holds multiple |Scoping| objects, which define sets of entity IDs (nodes, elements, etc.). | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Create and Populate a ScopingsContainer | ||||||||||||||||||||||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Create different node selections and organize them in a |ScopingsContainer|. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| .. jupyter-execute:: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Get the mesh from our model | ||||||||||||||||||||||||||
| mesh = model.metadata.meshed_region | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Create a ScopingsContainer | ||||||||||||||||||||||||||
| scopings_container = dpf.ScopingsContainer() | ||||||||||||||||||||||||||
| # Set labels for different selections | ||||||||||||||||||||||||||
| scopings_container.labels = ["selection_type"] | ||||||||||||||||||||||||||
| # Selection 1: First 10 nodes | ||||||||||||||||||||||||||
| first_nodes = dpf.Scoping(location=dpf.locations.nodal) | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lack of code comments here. It doesn't explain what each line is doing. |
||||||||||||||||||||||||||
| first_nodes.ids = list(range(1, 11)) | ||||||||||||||||||||||||||
| scopings_container.add_scoping(label_space={"selection_type": 0}, scoping=first_nodes) | ||||||||||||||||||||||||||
| # Selection 2: Every 10th node (sample) | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would put more space between the blocks so it can be more visual. |
||||||||||||||||||||||||||
| all_node_ids = mesh.nodes.scoping.ids | ||||||||||||||||||||||||||
| every_tenth = dpf.Scoping(location=dpf.locations.nodal) | ||||||||||||||||||||||||||
| every_tenth.ids = all_node_ids[::10] # Every 10th node | ||||||||||||||||||||||||||
| scopings_container.add_scoping(label_space={"selection_type": 1}, scoping=every_tenth) | ||||||||||||||||||||||||||
|
Comment on lines
+149
to
+152
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. example on the comment lines |
||||||||||||||||||||||||||
| # Selection 3: Last 10 nodes | ||||||||||||||||||||||||||
| last_nodes = dpf.Scoping(location=dpf.locations.nodal) | ||||||||||||||||||||||||||
| last_nodes.ids = all_node_ids[-10:] | ||||||||||||||||||||||||||
| scopings_container.add_scoping(label_space={"selection_type": 2}, scoping=last_nodes) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Display ScopingsContainer information | ||||||||||||||||||||||||||
| print(scopings_container) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Use ScopingsContainer with Operators | ||||||||||||||||||||||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| |ScopingsContainer| objects can be used with operators to apply operations to multiple selections. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| .. jupyter-execute:: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Create an operator to extract displacement on specific node sets | ||||||||||||||||||||||||||
| displacement_op = dpf.operators.result.displacement() | ||||||||||||||||||||||||||
| displacement_op.inputs.data_sources(data_sources) | ||||||||||||||||||||||||||
| displacement_op.inputs.mesh_scoping(scopings_container) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Evaluate to get results for all scopings | ||||||||||||||||||||||||||
| scoped_displacements = displacement_op.eval() | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| print(f"Displacement results for different node selections:") | ||||||||||||||||||||||||||
| print(scoped_displacements) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Working with MeshesContainer | ||||||||||||||||||||||||||
| ---------------------------- | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| A |MeshesContainer| stores multiple |MeshedRegion| objects. This is useful when working with different mesh configurations or time-dependent meshes. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Create a MeshesContainer | ||||||||||||||||||||||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Create a |MeshesContainer| with mesh data for different analysis configurations. | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. analysis configuration |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| .. jupyter-execute:: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Create a MeshesContainer | ||||||||||||||||||||||||||
| meshes_container = dpf.MeshesContainer() | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Set labels for different mesh configurations | ||||||||||||||||||||||||||
| meshes_container.labels = ["variation"] | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Get the original mesh | ||||||||||||||||||||||||||
| original_mesh = model.metadata.meshed_region | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Add original mesh | ||||||||||||||||||||||||||
| meshes_container.add_mesh({"variation": 0}, original_mesh) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Create a modified mesh (example: subset of elements) | ||||||||||||||||||||||||||
| # Get element scoping for first half of elements | ||||||||||||||||||||||||||
| all_element_ids = original_mesh.elements.scoping.ids | ||||||||||||||||||||||||||
| subset_element_ids = all_element_ids[:len(all_element_ids)//2] | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Create element scoping for subset | ||||||||||||||||||||||||||
| element_scoping = dpf.Scoping(location=dpf.locations.elemental) | ||||||||||||||||||||||||||
| element_scoping.ids = subset_element_ids | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Extract subset mesh using an operator | ||||||||||||||||||||||||||
| mesh_extract_op = dpf.operators.mesh.from_scoping() | ||||||||||||||||||||||||||
| mesh_extract_op.inputs.mesh(original_mesh) | ||||||||||||||||||||||||||
| mesh_extract_op.inputs.scoping(element_scoping) | ||||||||||||||||||||||||||
| subset_mesh = mesh_extract_op.eval() | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Add subset mesh to container | ||||||||||||||||||||||||||
| meshes_container.add_mesh({"variation": 1}, subset_mesh) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Display MeshesContainer information | ||||||||||||||||||||||||||
| print(meshes_container) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Collection Operations and Iteration | ||||||||||||||||||||||||||
| ------------------------------------ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Collections support various operations for data manipulation and analysis. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Iterate Through Collections | ||||||||||||||||||||||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| You can iterate through collections using different methods. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| .. jupyter-execute:: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Iterate through FieldsContainer by index | ||||||||||||||||||||||||||
| print("Iterating through displacement fields by index:") | ||||||||||||||||||||||||||
| for i in range(min(3, len(displacement_fc))): # Show first 3 fields | ||||||||||||||||||||||||||
| field = displacement_fc[i] | ||||||||||||||||||||||||||
| label_space = displacement_fc.get_label_space(i) | ||||||||||||||||||||||||||
| max_value = field.data.max() | ||||||||||||||||||||||||||
| print(f" Field {i}: {label_space}, max value: {max_value:.6f}") | ||||||||||||||||||||||||||
|
Comment on lines
+238
to
+242
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same thing here for the loop. |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| print("\nIterating through ScopingsContainer:") | ||||||||||||||||||||||||||
| for i, scoping in enumerate(scopings_container): | ||||||||||||||||||||||||||
| label_space = scopings_container.get_label_space(i) | ||||||||||||||||||||||||||
| print(f" Scoping {i}: {label_space}, size: {scoping.size}") | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Filter and Select from Collections | ||||||||||||||||||||||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| You can filter collections based on labels or criteria. | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which criteria? |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| .. jupyter-execute:: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Get specific fields from FieldsContainer by label criteria | ||||||||||||||||||||||||||
| # Get all fields of ``custom_fc`` where ``zone=1`` | ||||||||||||||||||||||||||
| zone_1_fields = custom_fc.get_fields({"zone": 1}) | ||||||||||||||||||||||||||
| print(f"\nFields in custom_fc with zone=1:") | ||||||||||||||||||||||||||
| for field in zone_1_fields: | ||||||||||||||||||||||||||
| print(field) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Other Built-in Collection Types | ||||||||||||||||||||||||||
| ------------------------------ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| DPF provides several built-in collection types for common DPF objects, implemented in their respective modules: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - :class:`ansys.dpf.core.fields_container.FieldsContainer` for fields | ||||||||||||||||||||||||||
| - :class:`ansys.dpf.core.meshes_container.MeshesContainer` for meshes | ||||||||||||||||||||||||||
| - :class:`ansys.dpf.core.scopings_container.ScopingsContainer` for scopings | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Additionally, the following specialized collection types are available (from ``collection_base.py``): | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| - :class:`ansys.dpf.core.collection_base.IntegralCollection` for integral types | ||||||||||||||||||||||||||
| - :class:`ansys.dpf.core.collection_base.IntCollection` for integers | ||||||||||||||||||||||||||
| - :class:`ansys.dpf.core.collection_base.FloatCollection` for floats | ||||||||||||||||||||||||||
| - :class:`ansys.dpf.core.collection_base.StringCollection` for strings | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| These built-in collections are optimized for their respective DPF types and should be used when working with fields, meshes, scopings, or basic types. For other supported types, you can use the :py:meth:`ansys.dpf.core.collection.Collection.collection_factory` method to create a custom collection class at runtime. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Using the Collection Factory | ||||||||||||||||||||||||||
| --------------------------- | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| .. note:: | ||||||||||||||||||||||||||
| Collections can only be made for types supported by DPF. Attempting to use unsupported or arbitrary Python types will result in an error. | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| The :py:meth:`ansys.dpf.core.collection.Collection.collection_factory` method allows you to create a collection class for any supported DPF type at runtime. This is useful when you want to group and manage objects that are not covered by the built-in collection types (such as FieldsContainer, MeshesContainer, or ScopingsContainer). | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| For example, you can create a collection for :class:`ansys.dpf.core.DataSources` objects: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| .. jupyter-execute:: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| from ansys.dpf.core import DataSources | ||||||||||||||||||||||||||
| from ansys.dpf.core import examples | ||||||||||||||||||||||||||
| from ansys.dpf.core.collection import Collection | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Create a collection class for DataSources | ||||||||||||||||||||||||||
| DataSourcesCollection = Collection.collection_factory(DataSources) | ||||||||||||||||||||||||||
| ds_collection = DataSourcesCollection() | ||||||||||||||||||||||||||
| ds_collection.labels = ["case"] | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Add DataSources objects to the collection | ||||||||||||||||||||||||||
| ds1 = DataSources("path/to/first/result/file.rst") | ||||||||||||||||||||||||||
| ds2 = DataSources("path/to/second/result/file.rst") | ||||||||||||||||||||||||||
| ds_collection.add_entry({"case": 0}, ds1) | ||||||||||||||||||||||||||
| ds_collection.add_entry({"case": 1}, ds2) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Show the collection | ||||||||||||||||||||||||||
| print(ds_collection) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| This approach allows you to leverage the powerful labeling and grouping features of DPF collections for any supported DPF object type, making your workflows more flexible and organized. | ||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.