Skip to content

Commit a850312

Browse files
anshlachambrafacantonPProfizi
authored
Feature: allow setting named dimensionless units in a Field (#2295)
Co-authored-by: Rafael Canton <[email protected]> Co-authored-by: Paul Profizi <[email protected]> Co-authored-by: PProfizi <[email protected]>
1 parent 9f8f63f commit a850312

File tree

3 files changed

+95
-8
lines changed

3 files changed

+95
-8
lines changed

src/ansys/dpf/core/field.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
from ansys import dpf
3232
from ansys.dpf.core import dimensionality, errors, meshed_region, scoping, time_freq_support
33+
from ansys.dpf.core.available_result import Homogeneity
3334
from ansys.dpf.core.common import (
3435
_get_size_of_list,
3536
locations,
@@ -617,12 +618,18 @@ def unit(self):
617618
return self.field_definition.unit
618619

619620
@unit.setter
620-
def unit(self, value):
621+
def unit(self, value: str | tuple[Homogeneity, str]):
621622
"""Change the unit for the field.
622623
624+
A single string is interpreted as a known physical unit with an associated homogeneity.
625+
626+
For DPF 11.0 (2026 R1) and above: A tuple of two strings is interpreted as a homogeneity and a unit name.
627+
If the homogeneity is :py:attr:`Homogeneity.dimensionless`, then the unit string is kept as a name.
628+
Otherwise, the homogeneity is ignored, and the unit string interpreted as a known physical unit with an associated homogeneity.
629+
623630
Parameters
624631
----------
625-
value : str
632+
value:
626633
Units for the field.
627634
628635
Examples
@@ -635,10 +642,24 @@ def unit(self, value):
635642
>>> my_field.unit
636643
'm'
637644
645+
646+
Named dimensionless unit.
647+
648+
>>> from ansys.dpf import core as dpf
649+
>>> from ansys.dpf.core.available_result import Homogeneity
650+
>>> my_field = dpf.Field(10)
651+
>>> my_field.unit = (Homogeneity.dimensionless, "dollars")
652+
>>> print(my_field.unit)
653+
'dollars'
654+
655+
Notes
656+
-----
657+
Setting a named dimensionless unit requires DPF 11.0 (2026 R1) or above.
658+
638659
"""
639-
fielddef = self.field_definition
640-
fielddef.unit = value
641-
self.field_definition = fielddef
660+
field_def = self.field_definition
661+
field_def.unit = value
662+
self.field_definition = field_def
642663

643664
@property
644665
def dimensionality(self):

src/ansys/dpf/core/field_definition.py

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222

2323
"""FieldDefinition."""
2424

25+
from __future__ import annotations
26+
2527
import traceback
2628
import warnings
2729

2830
from ansys.dpf.core import server as server_module
29-
from ansys.dpf.core.check_version import version_requires
31+
from ansys.dpf.core.available_result import Homogeneity
32+
from ansys.dpf.core.check_version import server_meet_version_and_raise, version_requires
3033
from ansys.dpf.core.common import natures, shell_layers
3134
from ansys.dpf.core.dimensionality import Dimensionality
3235
from ansys.dpf.gate import (
@@ -204,8 +207,44 @@ def is_of_quantity_type(self, quantity_type):
204207
return is_of_quantity_type
205208

206209
@unit.setter
207-
def unit(self, value):
208-
self._api.csfield_definition_set_unit(self, value, None, 0, 0, 0)
210+
def unit(self, value: str | tuple[Homogeneity, str]):
211+
"""Change the unit for the field definition.
212+
213+
A single string is interpreted as a known physical unit with an associated homogeneity.
214+
215+
For DPF 11.0 (2026 R1) and above: A tuple of two strings is interpreted as a homogeneity and a unit name.
216+
If the homogeneity is :py:attr:`Homogeneity.dimensionless`, then the unit string is kept as a name.
217+
Otherwise, the homogeneity is ignored, and the unit string interpreted as a known physical unit with an associated homogeneity.
218+
219+
Parameters
220+
----------
221+
value:
222+
Units for the field.
223+
224+
Notes
225+
-----
226+
Setting a named dimensionless unit requires DPF 11.0 (2026 R1) or above.
227+
228+
"""
229+
# setter with explicit homogeneity: homogeneity is taken into account if it is dimensionless
230+
if (
231+
isinstance(value, tuple)
232+
and len(value) == 2
233+
and isinstance(value[0], Homogeneity)
234+
and isinstance(value[1], str)
235+
):
236+
server_meet_version_and_raise(
237+
required_version="11.0",
238+
server=self._server,
239+
msg="Setting a named dimensionless unit requires DPF 11.0 (2026 R1) or above.",
240+
)
241+
# csfield_definition_set_unit will ignore the homogeneity if it is not dimensionless
242+
self._api.csfield_definition_set_unit(self, value[1], None, value[0].value, 0, 0)
243+
# standard unit setter, using string interpreter
244+
elif isinstance(value, str):
245+
self._api.csfield_definition_set_unit(self, value, None, 0, 0, 0)
246+
else:
247+
raise ValueError("Unit setter supports either string or tuple(Homogeneity, str)")
209248

210249
@location.setter
211250
def location(self, value):

tests/test_field.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
from ansys import dpf
3030
from ansys.dpf import core
3131
from ansys.dpf.core import FieldDefinition, operators as ops
32+
from ansys.dpf.core.available_result import Homogeneity
3233
from ansys.dpf.core.check_version import server_meet_version
3334
from ansys.dpf.core.common import locations, shell_layers
35+
from ansys.dpf.gate.errors import DPFServerException, DpfVersionNotSupported
3436
import conftest
3537
from conftest import SERVERS_VERSION_GREATER_THAN_OR_EQUAL_TO_8_0, running_docker
3638

@@ -1417,3 +1419,28 @@ def test_deep_copy_big_field_remote(server_type, server_type_remote_process):
14171419

14181420
out = dpf.core.core._deep_copy(field_a, server_type_remote_process)
14191421
assert np.allclose(out.data, data)
1422+
1423+
1424+
def test_set_units(server_type):
1425+
data = np.random.random(100)
1426+
field = dpf.core.field_from_array(data)
1427+
# use string setter with recognized string
1428+
field.unit = "m"
1429+
assert field.unit == "m"
1430+
1431+
if server_meet_version("11.0", server_type):
1432+
# use tuple(Homogeneity, string) setter
1433+
field.unit = (Homogeneity.dimensionless, "sones")
1434+
assert field.unit == "sones"
1435+
else:
1436+
with pytest.raises(DpfVersionNotSupported):
1437+
# use tuple(Homogeneity, string) setter
1438+
field.unit = (Homogeneity.dimensionless, "sones")
1439+
1440+
# use unrecognized string
1441+
with pytest.raises(DPFServerException):
1442+
field.unit = "sones"
1443+
1444+
# use wrong type of arguments
1445+
with pytest.raises(ValueError):
1446+
field.unit = 1.0

0 commit comments

Comments
 (0)