Skip to content

Commit dae9c73

Browse files
authored
local data updates only when modified (#133)
1 parent b0c891f commit dae9c73

File tree

8 files changed

+85
-16
lines changed

8 files changed

+85
-16
lines changed

ansys/dpf/core/cache.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,21 @@ def wrapper(self, *args, **kwargs):
119119
func(self, *args, **kwargs)
120120

121121
return wrapper
122+
123+
def _setter(func):
124+
"""Add a private attribute to the class (``self._is_set = True``)
125+
when a method with this decorator is used.
126+
127+
.. note::
128+
The method must be used as a decorator.
129+
"""
130+
131+
def wrapper(self, *args, **kwargs):
132+
"""Call the original function"""
133+
if hasattr(self, "_is_set"):
134+
self._is_set = True
135+
else:
136+
setattr(self, "_is_set", True)
137+
func(self, *args, **kwargs)
138+
139+
return wrapper

ansys/dpf/core/field.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -579,9 +579,9 @@ def deep_copy(self, server=None):
579579
Parameters
580580
----------
581581
server : :class:`ansys.dpf.core.server`, optional
582-
Server with the channel connected to the remote or local instance. The
583-
default is ``None``, in which case an attempt is made to use the global
584-
server.
582+
Server with the channel connected to the remote or local instance. The
583+
default is ``None``, in which case an attempt is made to use the global
584+
server.
585585
586586
Returns
587587
-------

ansys/dpf/core/field_base.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from ansys.dpf.core.common import natures, locations
44
from ansys.dpf.core import errors
55
from ansys.dpf.core import server as serverlib
6+
from ansys.dpf.core.cache import _setter
67

78
import numpy as np
89

@@ -657,6 +658,7 @@ def get_entity_data_by_id(self, id):
657658
raise ValueError(f"The id {id} doesn't exist in the scoping")
658659
return self.get_entity_data(index)
659660

661+
@_setter
660662
def append(self, data, scopingid):
661663
"""Add an entity data to the existing data.
662664
@@ -766,6 +768,7 @@ def data(self):
766768
return np.array(self._data_copy)
767769

768770
@data.setter
771+
@_setter
769772
def data(self, data):
770773
if self._is_property_field:
771774
if not isinstance(data[0], int) and not isinstance(data[0], np.int32):
@@ -834,6 +837,7 @@ def _data_pointer_as_list(self):
834837
return self._data_pointer_copy
835838

836839
@_data_pointer.setter
840+
@_setter
837841
def _data_pointer(self, data):
838842
if isinstance(data, (np.ndarray, np.generic)):
839843
self._data_pointer_copy = data.tolist()
@@ -870,14 +874,20 @@ def scoping(self):
870874
return self._scoping_copy
871875

872876
@scoping.setter
877+
@_setter
873878
def scoping(self, data):
874-
self._scoping_copy = data
879+
if not isinstance(data, scoping._LocalScoping):
880+
self._scoping_copy = data.as_local_scoping()
881+
else:
882+
self._scoping_copy = data
875883

876884
def release_data(self):
877885
"""Release the data."""
878-
super()._set_data(self._data_copy)
879-
super()._set_data_pointer(self._data_pointer_copy)
880-
self._scoping_copy.release_data()
886+
if hasattr(self, "_is_set") and self._is_set:
887+
super()._set_data(self._data_copy)
888+
super()._set_data_pointer(self._data_pointer_copy)
889+
super()._set_scoping(self._scoping_copy._owner_scoping)
890+
self._scoping_copy.release_data()
881891

882892
def __enter__(self):
883893
return self

ansys/dpf/core/model.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ def streams_provider(self):
344344
345345
Returns
346346
-------
347-
streams_provider : operators.metadata.streams_provider
347+
streams_provider : :class:`ansys.dpf.core.operators.metadata.streams_provider`
348348
349349
Examples
350350
--------
@@ -392,7 +392,7 @@ def meshed_region(self):
392392
393393
Returns
394394
-------
395-
mesh : :class:`ansys.dpf.core.meshed_region`
395+
mesh : :class:`ansys.dpf.core.meshed_region.MeshedRegion`
396396
Mesh
397397
"""
398398
# NOTE: this uses the cached mesh and we might consider
@@ -413,7 +413,7 @@ def mesh_provider(self):
413413
414414
Returns
415415
-------
416-
mesh_provider : class:`ansys.dpf.core.operators.mesh.mesh_provider`
416+
mesh_provider : :class:`ansys.dpf.core.operators.mesh.mesh_provider`
417417
Mesh provider operator.
418418
419419
"""
@@ -434,7 +434,7 @@ def result_info(self):
434434
435435
Returns
436436
-------
437-
result_info : :class:`ansys.dpf.core.ResultInfo`
437+
result_info : :class:`ansys.dpf.core.result_info.ResultInfo`
438438
"""
439439
self._cache_result_info()
440440

@@ -460,6 +460,6 @@ def named_selection(self, named_selection):
460460
461461
Returns
462462
-------
463-
named_selection : :class:`ansys.dpf.core.scoping`
463+
named_selection : :class:`ansys.dpf.core.scoping.Scoping`
464464
"""
465465
return self.meshed_region.named_selection(named_selection)

ansys/dpf/core/scoping.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from ansys.dpf.core.common import _common_progress_bar, locations
1414
from ansys.dpf.core import misc
1515
from ansys.grpc.dpf import base_pb2, scoping_pb2, scoping_pb2_grpc
16+
from ansys.dpf.core.cache import _setter
1617

1718

1819
class Scoping:
@@ -430,6 +431,7 @@ def _get_location(self):
430431
"""
431432
return self._location
432433

434+
@_setter
433435
def _set_location(self, loc=locations.nodal):
434436
"""
435437
Parameters
@@ -440,6 +442,7 @@ def _set_location(self, loc=locations.nodal):
440442
"""
441443
self._location = loc
442444

445+
@_setter
443446
@version_requires("2.1")
444447
def _set_ids(self, ids):
445448
"""
@@ -477,6 +480,7 @@ def _get_ids(self, np_array=False):
477480
else:
478481
return self._scoping_ids_copy
479482

483+
@_setter
480484
def set_id(self, index, scopingid):
481485
"""Set the ID of a scoping's index.
482486
@@ -494,6 +498,7 @@ def set_id(self, index, scopingid):
494498
self._scoping_ids_copy[index] = scopingid
495499
self._mapper[scopingid] = index
496500

501+
@_setter
497502
def append(self, id):
498503
self._scoping_ids_copy.append(id)
499504
self._mapper[id] = len(self)-1
@@ -530,8 +535,9 @@ def _get_index(self, scopingid):
530535

531536
def release_data(self):
532537
"""Release the data."""
533-
super()._set_ids(self._scoping_ids_copy)
534-
super()._set_location(self._location)
538+
if hasattr(self, "_is_set") and self._is_set:
539+
super()._set_ids(self._scoping_ids_copy)
540+
super()._set_location(self._location)
535541

536542
def __enter__(self):
537543
return self

ansys/dpf/core/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
def shutdown_global_server():
3737
try:
3838
if dpf.core.SERVER != None:
39-
del dpf.core.SERVER
39+
dpf.core.SERVER.__del__()
4040
except:
4141
pass
4242

tests/test_field.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ def test_local_field_append():
488488
with field_to_local.as_local_field() as f:
489489
for i in range(1, num_entities + 1):
490490
f.append([0.1 * i, 0.2 * i, 0.3 * i], i)
491+
assert f._is_set == True
491492
field = dpf.core.fields_factory.create_3d_vector_field(num_entities)
492493
for i in range(1, num_entities + 1):
493494
field.append([0.1 * i, 0.2 * i, 0.3 * i], i)
@@ -520,7 +521,7 @@ def test_local_elemental_nodal_field_append():
520521
with field_to_local.as_local_field() as f:
521522
for i in range(1, num_entities + 1):
522523
f.append([0.1 * i, 0.2 * i, 0.3 * i, 0.1 * i, 0.2 * i, 0.3 * i], i)
523-
524+
assert f._is_set == True
524525
assert np.allclose(field.data, field_to_local.data)
525526
assert np.allclose(field.scoping.ids, field_to_local.scoping.ids)
526527
assert len(field_to_local._data_pointer) == num_entities
@@ -532,6 +533,7 @@ def test_local_array_field_append():
532533
with field_to_local.as_local_field() as f:
533534
for i in range(1, num_entities + 1):
534535
f.append(np.array([0.1 * i, 0.2 * i, 0.3 * i]), i)
536+
assert f._is_set is True
535537
field = dpf.core.fields_factory.create_3d_vector_field(num_entities)
536538
for i in range(1, num_entities + 1):
537539
field.append(np.array([0.1 * i, 0.2 * i, 0.3 * i]), i)
@@ -588,6 +590,7 @@ def test_local_get_entity_data():
588590
assert np.allclose(
589591
f.get_entity_data_by_id(i), [[0.1 * i, 0.2 * i, 0.3 * i]]
590592
)
593+
assert hasattr(f, "_is_set") is True
591594

592595
with field_to_local.as_local_field() as f:
593596
for i in range(1, num_entities + 1):
@@ -596,6 +599,8 @@ def test_local_get_entity_data():
596599
f.get_entity_data_by_id(i), [[0.1 * i, 0.2 * i, 0.3 * i]]
597600
)
598601

602+
assert hasattr(f, "_is_set") is False
603+
599604

600605
def test_local_elemental_nodal_get_entity_data():
601606
num_entities = 100
@@ -615,6 +620,8 @@ def test_local_elemental_nodal_get_entity_data():
615620
f.get_entity_data_by_id(i),
616621
[[0.1 * i, 0.2 * i, 0.3 * i], [0.1 * i, 0.2 * i, 0.3 * i]],
617622
)
623+
assert hasattr(f, "_is_set") is True
624+
assert f._is_set is True
618625

619626
with field_to_local.as_local_field() as f:
620627
for i in range(1, num_entities + 1):
@@ -626,6 +633,7 @@ def test_local_elemental_nodal_get_entity_data():
626633
f.get_entity_data_by_id(i),
627634
[[0.1 * i, 0.2 * i, 0.3 * i], [0.1 * i, 0.2 * i, 0.3 * i]],
628635
)
636+
assert hasattr(f, "_is_set") is False
629637

630638

631639
def test_auto_delete_field_local():
@@ -689,6 +697,8 @@ def test_get_set_data_elemental_nodal_local_field():
689697
assert np.allclose(f._data_pointer, [0, 6])
690698
assert np.allclose(f.get_entity_data(0), [[0.1, 0.2, 0.3], [0.1, 0.2, 0.3]])
691699
assert np.allclose(f.get_entity_data(1), [[0.1, 0.2, 0.3], [0.1, 0.2, 0.4]])
700+
assert hasattr(f, "_is_set") is True
701+
assert f._is_set is True
692702

693703
assert np.allclose(
694704
field_to_local.data,
@@ -712,6 +722,8 @@ def test_get_set_data_elemental_nodal_local_field():
712722
assert np.allclose(f._data_pointer, [0, 6])
713723
assert np.allclose(f.get_entity_data(0), [[0.1, 0.2, 0.3], [0.1, 0.2, 0.3]])
714724
assert np.allclose(f.get_entity_data(1), [[0.1, 0.2, 0.3], [0.1, 0.2, 0.4]])
725+
assert hasattr(f, "_is_set") is True
726+
assert f._is_set is True
715727

716728
assert np.allclose(
717729
field_to_local.data,
@@ -737,6 +749,8 @@ def test_get_set_data_elemental_nodal_local_field():
737749
assert np.allclose(f._data_pointer, [0, 6])
738750
assert np.allclose(f.get_entity_data(0), [[0.1, 0.2, 0.3], [0.1, 0.2, 0.3]])
739751
assert np.allclose(f.get_entity_data(1), [[0.1, 0.2, 0.3], [0.1, 0.2, 0.4]])
752+
assert hasattr(f, "_is_set") is True
753+
assert f._is_set is True
740754

741755
assert np.allclose(
742756
field_to_local.data,
@@ -751,6 +765,20 @@ def test_get_set_data_elemental_nodal_local_field():
751765
)
752766

753767

768+
def test_get_set_scoping_local_field():
769+
field_to_local = dpf.core.fields_factory.create_3d_vector_field(
770+
2, location=dpf.core.locations.elemental_nodal
771+
)
772+
with field_to_local.as_local_field() as f:
773+
f.data = [[0.1, 0.2, 0.3], [0.1, 0.2, 0.3]]
774+
f.scoping = dpf.core.Scoping(ids=[3, 4])
775+
assert np.allclose(f.data, [[0.1, 0.2, 0.3], [0.1, 0.2, 0.3]])
776+
assert np.allclose(f.scoping_ids, [3, 4])
777+
assert np.allclose(f.scoping.ids, [3, 4])
778+
assert np.allclose(field_to_local.data, [[0.1, 0.2, 0.3], [0.1, 0.2, 0.3]])
779+
assert np.allclose(field_to_local.scoping.ids, [3, 4])
780+
781+
754782
def test_empty_data_field():
755783
field_to_local = dpf.core.fields_factory.create_3d_vector_field(100)
756784
data = [1.0, 2.0, 3.0]

tests/test_scoping.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,17 @@ def test_as_local_scoping():
202202
loc.append(i + 1)
203203
assert loc.id(i) == i + 1
204204
assert loc.index(i + 1) == i
205+
assert hasattr(loc, "_is_set") is True
206+
assert loc._is_set is True
205207
assert scop.ids == list(range(1, 101))
206208
assert scop.location == "Nodal"
207209
with scop.as_local_scoping() as loc:
208210
assert loc.location == "Nodal"
209211
for i in range(0, 100):
210212
assert loc.id(i) == i + 1
211213
assert loc.index(i + 1) == i
214+
assert hasattr(loc, "_is_set") is False
215+
212216

213217
def test_as_local_scoping2():
214218
scop = Scoping()
@@ -218,13 +222,16 @@ def test_as_local_scoping2():
218222
for i in range(0, 100):
219223
assert loc.id(i) == i + 1
220224
assert loc.index(i + 1) == i
225+
assert hasattr(loc, "_is_set") is True
226+
assert loc._is_set is True
221227
assert scop.ids == list(range(1, 101))
222228
assert scop.location == "Nodal"
223229
with scop.as_local_scoping() as loc:
224230
assert loc.location == "Nodal"
225231
for i in range(0, 100):
226232
assert loc.id(i) == i + 1
227233
assert loc.index(i + 1) == i
234+
assert hasattr(loc, "_is_set") is False
228235

229236

230237
def test_auto_delete_scoping_local():

0 commit comments

Comments
 (0)