Skip to content

Commit b8ab061

Browse files
committed
Merge branch 'develop' into release-0.6.0
2 parents c065f54 + 494cab2 commit b8ab061

31 files changed

+1112
-157
lines changed

ansys/dpf/core/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from ansys.dpf.core.field import Field, FieldDefinition
2121
from ansys.dpf.core.dimensionality import Dimensionality
2222
from ansys.dpf.core.property_field import PropertyField
23+
from ansys.dpf.core.string_field import StringField
2324
from ansys.dpf.core.fields_container import FieldsContainer
2425
from ansys.dpf.core.meshes_container import MeshesContainer
2526
from ansys.dpf.core.scopings_container import ScopingsContainer
@@ -50,6 +51,7 @@
5051
make_tmp_dir_server,
5152
)
5253
from ansys.dpf.core.time_freq_support import TimeFreqSupport
54+
from ansys.dpf.core.generic_support import GenericSupport
5355
from ansys.dpf.core.meshed_region import MeshedRegion
5456
from ansys.dpf.core.elements import element_types
5557
from ansys.dpf.core.result_info import ResultInfo

ansys/dpf/core/_custom_operators_helpers.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from ansys.dpf.gate import capi, external_operator_capi
22
from enum import Enum
3+
34
from ansys.dpf.core import (
45
field, property_field, scoping, collection, data_sources, meshed_region, time_freq_support, \
56
workflow, data_tree, dpf_operator, fields_container, scopings_container, \
6-
meshes_container, result_info
7+
meshes_container, result_info, string_field
78
)
89

910
external_operator_api = external_operator_capi.ExternalOperatorCAPI
@@ -21,6 +22,7 @@ def __operator_main__(operator_functor, data):
2122
(float, external_operator_api.external_operator_put_out_double),
2223
(field.Field, external_operator_api.external_operator_put_out_field),
2324
(property_field.PropertyField, external_operator_api.external_operator_put_out_property_field),
25+
(string_field.StringField, external_operator_api.external_operator_put_out_string_field),
2426
(scoping.Scoping, external_operator_api.external_operator_put_out_scoping),
2527
(collection.Collection, external_operator_api.external_operator_put_out_collection),
2628
(data_sources.DataSources, external_operator_api.external_operator_put_out_data_sources),
@@ -41,6 +43,8 @@ def __operator_main__(operator_functor, data):
4143
(field.Field, external_operator_api.external_operator_get_in_field, "field"),
4244
(property_field.PropertyField, external_operator_api.external_operator_get_in_property_field,
4345
"property_field"),
46+
(string_field.StringField, external_operator_api.external_operator_get_in_string_field,
47+
"string_field"),
4448
(scoping.Scoping, external_operator_api.external_operator_get_in_scoping,
4549
"scoping"),
4650
(fields_container.FieldsContainer,

ansys/dpf/core/available_result.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ def __init__(self, availableresult):
112112
self._properties = {"scripting_name": availableresult.properties["scripting_name"],
113113
"location": availableresult.properties["loc_name"]}
114114
self._sub_res = availableresult.sub_res
115+
self._qualifiers = availableresult.qualifiers
115116

116117
def __str__(self):
117118
txt = (
@@ -214,6 +215,13 @@ def physical_name(self) -> str:
214215
"""Name of the result with spaces"""
215216
return self._physics_name
216217

218+
@property
219+
def qualifiers(self) -> list:
220+
"""Returns the list of qualifiers (equivalent to label spaces)
221+
available for a given Result. These qualifiers can then be used to request the result
222+
on specified locations/properties.
223+
"""
224+
return self._qualifiers
217225

218226
_result_properties = {
219227
"S": {"location": "ElementalNodal", "scripting_name": "stress"},
@@ -253,10 +261,13 @@ def available_result_from_name(name) -> AvailableResult:
253261
for key, item in _result_properties.items():
254262
if item["scripting_name"] == name:
255263
from types import SimpleNamespace
256-
availableresult = SimpleNamespace(name=key, physicsname=name, ncomp=None,
257-
dimensionality=None,
258-
homogeneity=None,
259-
unit=None, sub_res={},
260-
properties={"loc_name": item["location"],
261-
"scripting_name": name})
264+
availableresult = SimpleNamespace(
265+
name=key, physicsname=name, ncomp=None,
266+
dimensionality=None,
267+
homogeneity=None,
268+
unit=None, sub_res={},
269+
properties={"loc_name": item["location"],
270+
"scripting_name": name},
271+
qualifiers=[])
272+
262273
return AvailableResult(availableresult)

ansys/dpf/core/collection.py

Lines changed: 61 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,13 @@
1212

1313
from ansys.dpf.core.server_types import BaseServer
1414
from ansys.dpf.core.scoping import Scoping
15-
from ansys.dpf.core.time_freq_support import TimeFreqSupport
15+
from ansys.dpf.core.label_space import LabelSpace
1616
from ansys.dpf.core import server as server_module
1717
from ansys.dpf.gate import (
1818
collection_capi,
1919
collection_grpcapi,
20-
label_space_capi,
21-
label_space_grpcapi,
2220
data_processing_capi,
2321
data_processing_grpcapi,
24-
object_handler,
2522
dpf_vector,
2623
dpf_array
2724
)
@@ -216,7 +213,9 @@ def _get_entries(self, label_space_or_index):
216213
Entries corresponding to the request.
217214
"""
218215
if isinstance(label_space_or_index, dict):
219-
client_label_space = self._create_client_label_space(label_space_or_index)
216+
client_label_space = LabelSpace(
217+
label_space=label_space_or_index, obj=self, server=self._server
218+
)
220219
num = self._api.collection_get_num_obj_for_label_space(self, client_label_space)
221220
out = []
222221
for i in range(0, num):
@@ -268,9 +267,10 @@ def get_label_space(self, index):
268267
Scoping of the requested entry. For example,
269268
``{"time": 1, "complex": 0}``.
270269
"""
271-
return self._create_dict_from_client_label_space(
272-
self._api.collection_get_obj_label_space_by_index(self, index)
273-
)
270+
return LabelSpace(
271+
label_space=self._api.collection_get_obj_label_space_by_index(self, index),
272+
server=self._server
273+
).__dict__()
274274

275275
def get_available_ids_for_label(self, label="time"):
276276
"""Retrieve the IDs assigned to an input label.
@@ -333,11 +333,6 @@ def __getitem__(self, index):
333333

334334
return self._get_entries(index)
335335

336-
@property
337-
def _label_space_api(self):
338-
return self._server.get_api_for_type(capi=label_space_capi.LabelSpaceCAPI,
339-
grpcapi=label_space_grpcapi.LabelSpaceGRPCAPI)
340-
341336
@property
342337
def _data_processing_core_api(self):
343338
core_api = self._server.get_api_for_type(
@@ -346,27 +341,6 @@ def _data_processing_core_api(self):
346341
core_api.init_data_processing_environment(self)
347342
return core_api
348343

349-
def _create_client_label_space(self, label_space):
350-
client_label_space = object_handler.ObjHandler(
351-
self._data_processing_core_api,
352-
self._label_space_api.label_space_new_for_object(self)
353-
)
354-
for key, id in label_space.items():
355-
self._label_space_api.label_space_add_data(client_label_space, key, id)
356-
return client_label_space
357-
358-
def _create_dict_from_client_label_space(self, client_label_space):
359-
if isinstance(client_label_space, dict):
360-
return client_label_space
361-
out = {}
362-
client_label_space = object_handler.ObjHandler(
363-
self._data_processing_core_api, client_label_space
364-
)
365-
for i in range(0, self._label_space_api.label_space_get_size(client_label_space)):
366-
out[self._label_space_api.label_space_get_labels_name(client_label_space, i)] = \
367-
self._label_space_api.label_space_get_labels_value(client_label_space, i)
368-
return out
369-
370344
def _add_entry(self, label_space, entry):
371345
"""Update or add an entry at a requested label space.
372346
@@ -377,7 +351,7 @@ def _add_entry(self, label_space, entry):
377351
entry : Field or Scoping
378352
DPF entry to add.
379353
"""
380-
client_label_space = self._create_client_label_space(label_space)
354+
client_label_space = LabelSpace(label_space=label_space, obj=self, server=self._server)
381355
self._api.collection_add_entry(self, client_label_space, entry)
382356

383357
def _get_time_freq_support(self):
@@ -387,6 +361,7 @@ def _get_time_freq_support(self):
387361
-------
388362
time_freq_support : TimeFreqSupport
389363
"""
364+
from ansys.dpf.core.time_freq_support import TimeFreqSupport
390365
from ansys.dpf.gate import support_capi, support_grpcapi, object_handler, \
391366
data_processing_capi, data_processing_grpcapi
392367
data_api = self._server.get_api_for_type(
@@ -581,3 +556,54 @@ def get_integral_entries(self):
581556
return dpf_array.DPFArray(vec)
582557
except NotImplementedError:
583558
return self._api.collection_get_data_as_double(self, 0)
559+
560+
561+
class StringCollection(Collection):
562+
"""Creates a collection of strings with a list.
563+
564+
The collection of integral is the equivalent of an array of
565+
data sent server side. It can be used to efficiently stream
566+
large data to the server.
567+
568+
Parameters
569+
----------
570+
list : list[float], numpy.array
571+
list to transfer server side
572+
573+
Notes
574+
-----
575+
Used by default by the ``'Operator'`` and the``'Workflow'`` when a
576+
list is connected or returned.
577+
"""
578+
579+
def __init__(self, list=None, server=None, collection=None, local: bool = False):
580+
super().__init__(server=server, collection=collection)
581+
self._sub_type = str
582+
if self._internal_obj is None:
583+
if self._server.has_client():
584+
if local:
585+
self._internal_obj = self._api.collection_of_string_new_local(
586+
self._server.client
587+
)
588+
else:
589+
self._internal_obj = self._api.collection_of_string_new_on_client(
590+
self._server.client
591+
)
592+
else:
593+
self._internal_obj = self._api.collection_of_string_new()
594+
if list is not None:
595+
self._set_integral_entries(list)
596+
597+
def create_subtype(self, obj_by_copy):
598+
return str(obj_by_copy)
599+
600+
def _set_integral_entries(self, input):
601+
for s in input:
602+
self._api.collection_add_string_entry(self, s)
603+
604+
def get_integral_entries(self):
605+
num = self._api.collection_get_size(self)
606+
out = []
607+
for i in range(num):
608+
out.append(self._api.collection_get_string_entry(self, i))
609+
return out

ansys/dpf/core/common.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
import re
1010
import sys
1111
from enum import Enum
12-
import numpy as np
12+
1313
from ansys.dpf.core.misc import module_exists
1414
from ansys.dpf.gate.common import locations, ProgressBarBase # noqa: F401
15+
from ansys.dpf.gate.dpf_vector import get_size_of_list as _get_size_of_list # noqa: F401
1516

1617
def _camel_to_snake_case(name):
1718
return re.sub(r"(?<!^)(?=[A-Z])", "_", name).lower()
@@ -82,9 +83,10 @@ class types(Enum):
8283
operator = 19
8384
data_tree = 20
8485
vec_string = 21
85-
fields_container = 22
86-
scopings_container = 23
87-
meshes_container = 24
86+
string_field = 22
87+
fields_container = 23
88+
scopings_container = 24
89+
meshes_container = 25
8890

8991

9092
def types_enum_to_types():
@@ -97,6 +99,7 @@ def types_enum_to_types():
9799
meshed_region,
98100
meshes_container,
99101
property_field,
102+
string_field,
100103
result_info,
101104
scoping,
102105
scopings_container,
@@ -128,6 +131,7 @@ def types_enum_to_types():
128131
types.scoping: scoping.Scoping,
129132
types.vec_int: dpf_vector.DPFVectorInt,
130133
types.vec_double: dpf_vector.DPFVectorDouble,
134+
types.string_field: string_field.StringField,
131135
}
132136

133137

@@ -255,11 +259,3 @@ def _common_progress_bar(text, unit, tot_size=None):
255259

256260
def _common_percentage_progress_bar(text):
257261
return TqdmProgressBar(text, "%", 100)
258-
259-
260-
def _get_size_of_list(list):
261-
if isinstance(list, (np.generic, np.ndarray)):
262-
return list.size
263-
elif not hasattr(list, '__iter__'):
264-
return 1
265-
return len(list)

ansys/dpf/core/data_tree.py

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@
1010

1111
from ansys.dpf.core.mapping_types import types
1212
from ansys.dpf.core import server as server_module
13+
from ansys.dpf.core import collection
1314
from ansys.dpf.core import errors
1415
from ansys.dpf.gate import (
1516
dpf_data_tree_abstract_api,
1617
dpf_data_tree_capi,
1718
dpf_data_tree_grpcapi,
1819
data_processing_capi,
1920
data_processing_grpcapi,
20-
collection_capi,
21-
collection_grpcapi,
22-
object_handler,
2321
integral_types,
2422
)
2523

@@ -139,19 +137,11 @@ def add_data(self, key, value):
139137
self, key, value, len(value)
140138
)
141139
elif len(value) > 0 and isinstance(value[0], str):
142-
if self._server.has_client():
143-
coll_obj = object_handler.ObjHandler(
144-
data_processing_api=self._core_api,
145-
internal_obj=self._coll_api.collection_of_string_new_local(
146-
self._server.client
147-
)
148-
)
149-
else:
150-
coll_obj = object_handler.ObjHandler(
151-
data_processing_api=self._core_api,
152-
internal_obj=self._coll_api.collection_of_string_new())
153-
for s in value:
154-
self._coll_api.collection_add_string_entry(coll_obj, s)
140+
coll_obj = collection.StringCollection(
141+
list=value,
142+
local=True,
143+
server=self._server
144+
)
155145
self._api.dpf_data_tree_set_string_collection_attribute(
156146
self, key, coll_obj
157147
)
@@ -184,14 +174,6 @@ def _core_api(self):
184174
core_api.init_data_processing_environment(self)
185175
return core_api
186176

187-
@property
188-
def _coll_api(self):
189-
coll_api = self._server.get_api_for_type(
190-
capi=collection_capi.CollectionCAPI,
191-
grpcapi=collection_grpcapi.CollectionGRPCAPI)
192-
coll_api.init_collection_environment(self)
193-
return coll_api
194-
195177
def to_fill(self):
196178
"""
197179
This method allows to access and modify the local copy of the data_tree
@@ -458,14 +440,11 @@ def get_as(self, name, type_to_return=types.string):
458440
self._api.dpf_data_tree_get_vec_int_attribute(self, name, out, out.internal_size)
459441
out = out.tolist()
460442
elif type_to_return == types.vec_string:
461-
coll_obj = object_handler.ObjHandler(
462-
data_processing_api=self._core_api,
463-
internal_obj=self._api.dpf_data_tree_get_string_collection_attribute(self, name)
443+
coll_obj = collection.StringCollection(
444+
collection=self._api.dpf_data_tree_get_string_collection_attribute(self, name),
445+
server=self._server
464446
)
465-
num = self._coll_api.collection_get_size(coll_obj)
466-
out = []
467-
for i in range(num):
468-
out.append(self._coll_api.collection_get_string_entry(coll_obj, i))
447+
out = coll_obj.get_integral_entries()
469448
elif type_to_return == types.data_tree:
470449
obj = self._api.dpf_data_tree_get_sub_tree(self, name)
471450
out = DataTree(data_tree=obj, server=self._server)

0 commit comments

Comments
 (0)