Skip to content

Commit cd62205

Browse files
committed
Merge branch 'master' of https://github.com/pyansys/pydpf-core into test/cff_plugin/res_info
2 parents ffc68f7 + 819df92 commit cd62205

File tree

10 files changed

+671
-110
lines changed

10 files changed

+671
-110
lines changed

docs/source/concepts/concepts.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Here are descriptions for key DPF terms:
1919
- **Location:** Type of topology associated with the data container. DPF
2020
uses three different spatial locations for finite element data: ``Nodal``,
2121
``Elemental``, and ``ElementalNodal``.
22-
- **Operators:** Objects that are used to create and transform the data.
22+
- **Operators:** Objects that are used to create, transform, and stream the data.
2323
An operator is composed of a **core** and **pins**. The core handles the
2424
calculation, and the pins provide input data to and output data from
2525
the operator.
@@ -28,6 +28,9 @@ Here are descriptions for key DPF terms:
2828
the support can be a mesh, geometrical entity, or time or frequency values.
2929
- **Workflow:** Global entity that is used to evaluate the data produced
3030
by chained operators.
31+
- **Meshed region:** Entity describing a mesh. Node and element scopings,
32+
element types, connectivity (list of node indices composing each element) and
33+
node coordinates are the fundamental entities composing the meshed region.
3134

3235
Scoping
3336
-------
@@ -69,7 +72,7 @@ This image summarizes the preceding concepts:
6972

7073
Operators
7174
---------
72-
You use :ref:`ref_dpf_operators_reference` to create and transform the data. An
75+
You use :ref:`ref_dpf_operators_reference` to create, transform, and stream the data. An
7376
*operator* is composed of a core and input and output pins.
7477

7578
- The core handles the calculation.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
:orphan:
2+
3+
=========
4+
Operators
5+
=========
6+
7+
Loading operators.
8+
9+
.. raw:: html
10+
11+
<iframe
12+
src="_static/dpf_operators.html"
13+
style="
14+
position: fixed;
15+
top: 36px;
16+
bottom: 0px;
17+
right: 0px;
18+
width: 100%;
19+
border: none;
20+
margin: 0;
21+
padding: 0;
22+
overflow: hidden;
23+
z-index: 1000;
24+
height: 100%;
25+
">
26+
</iframe>

docs/source/user_guide/operators.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Operators
66

77
.. include:: <isonum.txt>
88

9-
An operator is the only object that is used to create and transform
9+
An operator is the main object that is used to create, transform, and stream
1010
data. In DPF, you use operators to load, operate on, and output data.
1111

1212
Each operator contains ``input`` and ``output`` attributes, which

src/ansys/dpf/core/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@
8787
LicenseContextManager
8888
)
8989
from ansys.dpf.core.unit_system import UnitSystem, unit_systems
90+
from ansys.dpf.core.any import Any
91+
from ansys.dpf.core.generic_data_container import GenericDataContainer
9092

9193
# for matplotlib
9294
# solves "QApplication: invalid style override passed, ignoring it."

src/ansys/dpf/core/any.py

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
"""
2+
.. _ref_any:
3+
4+
Any
5+
====================
6+
"""
7+
import traceback
8+
import warnings
9+
10+
import ansys.dpf.core.server_types
11+
from ansys.dpf.core import server as server_module
12+
from ansys.dpf.core import errors
13+
from ansys.dpf.core.common import type_to_internal_object_keyword
14+
15+
16+
class Any:
17+
"""Common wrapper representing any supported DPF Data Types.
18+
19+
Parameters
20+
----------
21+
any : ctypes.c_void_p, ansys.grpc.dpf.any_pb2.Any message, optional # noqa: E501
22+
server : DPFServer, optional
23+
Server with channel connected to the remote or local instance.
24+
The default is ``None``, in which case an attempt is made to use the
25+
global server.
26+
27+
Notes
28+
-----
29+
Class available with server's version starting at 6.2 (Ansys 2024R1).
30+
"""
31+
32+
def __init__(self, any_dpf=None, server=None):
33+
# step 1: get server
34+
self._server = server_module.get_or_create_server(server)
35+
36+
if any_dpf is None and not self._server.meet_version("7.0"):
37+
raise errors.DpfVersionNotSupported("7.0")
38+
39+
self._api_instance = None
40+
41+
# step 2: if object exists, take the instance, else create it
42+
if any_dpf is not None:
43+
self._internal_obj = any_dpf
44+
45+
self._api.init_any_environment(self) # creates stub when gRPC
46+
47+
self._internal_type = None
48+
self._get_as_method = None
49+
50+
@staticmethod
51+
def _type_to_new_from_get_as_method(any_dpf):
52+
from ansys.dpf.core import (
53+
field,
54+
property_field,
55+
generic_data_container,
56+
string_field,
57+
scoping,
58+
)
59+
60+
return [
61+
(
62+
int,
63+
any_dpf._api.any_new_from_int,
64+
any_dpf._api.any_get_as_int,
65+
any_dpf._api.any_new_from_int_on_client,
66+
),
67+
(
68+
str,
69+
any_dpf._api.any_new_from_string,
70+
any_dpf._api.any_get_as_string,
71+
any_dpf._api.any_new_from_string_on_client,
72+
),
73+
(
74+
float,
75+
any_dpf._api.any_new_from_double,
76+
any_dpf._api.any_get_as_double,
77+
any_dpf._api.any_new_from_double_on_client,
78+
),
79+
(field.Field, any_dpf._api.any_new_from_field, any_dpf._api.any_get_as_field),
80+
(
81+
property_field.PropertyField,
82+
any_dpf._api.any_new_from_property_field,
83+
any_dpf._api.any_get_as_property_field,
84+
),
85+
(
86+
string_field.StringField,
87+
any_dpf._api.any_new_from_string_field,
88+
any_dpf._api.any_get_as_string_field,
89+
),
90+
(
91+
generic_data_container.GenericDataContainer,
92+
any_dpf._api.any_new_from_generic_data_container,
93+
any_dpf._api.any_get_as_generic_data_container,
94+
),
95+
(
96+
scoping.Scoping,
97+
any_dpf._api.any_new_from_scoping,
98+
any_dpf._api.any_get_as_scoping,
99+
),
100+
]
101+
102+
@staticmethod
103+
def new_from(obj, server=None):
104+
"""Return an Any instance from the given object.
105+
106+
Parameters
107+
----------
108+
obj : Object wrap as an Any
109+
110+
Returns
111+
-------
112+
any : Any
113+
Wrapped any type.
114+
"""
115+
116+
innerServer = server if server is not None else obj._server
117+
118+
if not innerServer.meet_version("7.0"):
119+
raise errors.DpfVersionNotSupported("7.0")
120+
121+
any_dpf = Any(server=innerServer)
122+
123+
for type_tuple in Any._type_to_new_from_get_as_method(any_dpf):
124+
if isinstance(obj, type_tuple[0]):
125+
# call respective new_from function
126+
if isinstance(server, ansys.dpf.core.server_types.InProcessServer) or not (
127+
isinstance(obj, int) or isinstance(obj, str) or isinstance(obj, float)
128+
):
129+
any_dpf._internal_obj = type_tuple[1](obj)
130+
else:
131+
any_dpf._internal_obj = type_tuple[3](innerServer.client, obj)
132+
# store get_as & type for casting back to original type
133+
any_dpf._internal_type = type_tuple[0]
134+
any_dpf._get_as_method = type_tuple[2]
135+
136+
return any_dpf
137+
138+
raise TypeError(f"{obj.__class__} is not currently supported by the Any class.")
139+
140+
@property
141+
def _api(self):
142+
from ansys.dpf.gate import any_capi, any_grpcapi
143+
144+
if not self._api_instance:
145+
self._api_instance = self._server.get_api_for_type(
146+
capi=any_capi.AnyCAPI, grpcapi=any_grpcapi.AnyGRPCAPI
147+
)
148+
149+
return self._api_instance
150+
151+
def __str__(self):
152+
"""Describe the entity.
153+
154+
Returns
155+
-------
156+
description : str
157+
Description of the entity.
158+
"""
159+
from ansys.dpf.core.core import _description
160+
161+
return _description(self._internal_obj, self._server)
162+
163+
def cast(self, output_type=None):
164+
"""Cast the Any back to its original type.
165+
166+
Parameters
167+
----------
168+
output_type: output_type, optional
169+
Used when the Any instance was retrieved from the server.
170+
Not necessary when the instance was created using the
171+
:func:`ansys.dpf.core.Any.new_from`
172+
173+
Returns
174+
-------
175+
type
176+
Original object instance
177+
"""
178+
179+
self._internal_type = output_type if output_type is not None else self._internal_type
180+
181+
for type_tuple in Any._type_to_new_from_get_as_method(self):
182+
if self._internal_type == type_tuple[0]:
183+
# call the get_as function for the appropriate type
184+
internal_obj = type_tuple[2](self)
185+
if (
186+
self._internal_type is int
187+
or self._internal_type is str
188+
or self._internal_type is float
189+
):
190+
obj = internal_obj
191+
else:
192+
# get current type's constructors' variable keyword for passing the internal_obj
193+
internal_obj_keyword = type_to_internal_object_keyword()[type_tuple[0]]
194+
195+
# wrap parameters in a dictionary for parameters expansion when calling
196+
# constructor
197+
keyword_args = {internal_obj_keyword: internal_obj, "server": self._server}
198+
# call constructor
199+
obj = type_tuple[0](**keyword_args)
200+
201+
return obj
202+
203+
raise TypeError(f"{output_type} is not currently supported by the Any class.")
204+
205+
def __del__(self):
206+
try:
207+
if hasattr(self, "_deleter_func"):
208+
obj = self._deleter_func[1](self)
209+
if obj is not None:
210+
self._deleter_func[0](obj)
211+
except Exception:
212+
warnings.warn(traceback.format_exc())

src/ansys/dpf/core/common.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,3 +289,47 @@ def _common_progress_bar(text, unit, tot_size=None):
289289

290290
def _common_percentage_progress_bar(text):
291291
return TqdmProgressBar(text, "%", 100)
292+
293+
294+
def type_to_internal_object_keyword():
295+
from ansys.dpf.core import (
296+
cyclic_support,
297+
data_sources,
298+
field,
299+
fields_container,
300+
meshed_region,
301+
meshes_container,
302+
property_field,
303+
string_field,
304+
custom_type_field,
305+
result_info,
306+
scoping,
307+
scopings_container,
308+
time_freq_support,
309+
dpf_operator,
310+
data_tree,
311+
workflow,
312+
streams_container,
313+
generic_data_container,
314+
)
315+
316+
return {
317+
field.Field: "field",
318+
property_field.PropertyField: "property_field",
319+
string_field.StringField: "string_field",
320+
custom_type_field.CustomTypeField: "field",
321+
scoping.Scoping: "scoping",
322+
fields_container.FieldsContainer: "fields_container",
323+
scopings_container.ScopingsContainer: "scopings_container",
324+
meshes_container.MeshesContainer: "meshes_container",
325+
streams_container.StreamsContainer: "streams_container",
326+
data_sources.DataSources: "data_sources",
327+
cyclic_support.CyclicSupport: "cyclic_support",
328+
meshed_region.MeshedRegion: "mesh",
329+
result_info.ResultInfo: "result_info",
330+
time_freq_support.TimeFreqSupport: "time_freq_support",
331+
workflow.Workflow: "workflow",
332+
data_tree.DataTree: "data_tree",
333+
dpf_operator.Operator: "operator",
334+
generic_data_container.GenericDataContainer: "generic_data_container",
335+
}

0 commit comments

Comments
 (0)