ansys-units 0.5.dev0__tar.gz → 0.6.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/PKG-INFO +4 -4
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/pyproject.toml +4 -4
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/__init__.py +28 -13
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/dimensions.py +1 -4
- ansys_units-0.6.dev0/src/ansys/units/quantity_dimensions.py +267 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/systems.py +2 -1
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/unit.py +2 -0
- ansys_units-0.6.dev0/src/ansys/units/variable_descriptor/__init__.py +50 -0
- ansys_units-0.6.dev0/src/ansys/units/variable_descriptor/strategy.py +240 -0
- ansys_units-0.6.dev0/src/ansys/units/variable_descriptor/variable_descriptor.py +270 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/LICENSE +0 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/README.rst +0 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/_constants.py +0 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/_version.py +0 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/base_dimensions.py +0 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/cfg.yaml +0 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/docs/.gitignore +0 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/quantity.py +0 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/quantity_tables/bt_table.yaml +0 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/quantity_tables/cgs_table.yaml +0 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/quantity_tables/si_table.yaml +0 -0
- {ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/unit_registry.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ansys-units
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.dev0
|
|
4
4
|
Summary: Pythonic interface for units, unit systems, and unit conversions.
|
|
5
5
|
Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
6
6
|
Maintainer-email: "ANSYS, Inc." <pyansys.core@ansys.com>
|
|
@@ -19,7 +19,7 @@ Requires-Dist: importlib-metadata>=4.0
|
|
|
19
19
|
Requires-Dist: pyyaml>=6.0
|
|
20
20
|
Requires-Dist: ansys-sphinx-theme==1.3.2 ; extra == "doc"
|
|
21
21
|
Requires-Dist: pdf2image==1.17.0 ; extra == "doc"
|
|
22
|
-
Requires-Dist: quarto-cli==1.
|
|
22
|
+
Requires-Dist: quarto-cli==1.7.29 ; extra == "doc"
|
|
23
23
|
Requires-Dist: matplotlib==3.10.1 ; extra == "doc"
|
|
24
24
|
Requires-Dist: numpydoc==1.8.0 ; extra == "doc"
|
|
25
25
|
Requires-Dist: Sphinx==7.4.7 ; extra == "doc"
|
|
@@ -27,8 +27,8 @@ Requires-Dist: sphinx-copybutton==0.5.2 ; extra == "doc"
|
|
|
27
27
|
Requires-Dist: sphinx-gallery==0.19.0 ; extra == "doc"
|
|
28
28
|
Requires-Dist: sphinx-toggleprompt==0.6.0 ; extra == "doc"
|
|
29
29
|
Requires-Dist: numpy==2.2.3 ; extra == "lists"
|
|
30
|
-
Requires-Dist: pytest==8.3.
|
|
31
|
-
Requires-Dist: pytest-cov==6.
|
|
30
|
+
Requires-Dist: pytest==8.3.5 ; extra == "tests"
|
|
31
|
+
Requires-Dist: pytest-cov==6.1.1 ; extra == "tests"
|
|
32
32
|
Requires-Dist: pytest-mock==3.14.0 ; extra == "tests"
|
|
33
33
|
Requires-Dist: pint==0.24.4 ; extra == "tests"
|
|
34
34
|
Project-URL: Documentation, https://ansunits.docs.pyansys.com
|
|
@@ -5,7 +5,7 @@ build-backend = "flit_core.buildapi"
|
|
|
5
5
|
[project]
|
|
6
6
|
# Check https://flit.readthedocs.io/en/latest/pyproject_toml.html for all available sections
|
|
7
7
|
name = "ansys-units"
|
|
8
|
-
version = "0.
|
|
8
|
+
version = "0.6.dev0"
|
|
9
9
|
description = "Pythonic interface for units, unit systems, and unit conversions."
|
|
10
10
|
readme = "README.rst"
|
|
11
11
|
requires-python = ">=3.9,<4"
|
|
@@ -32,7 +32,7 @@ dependencies = [
|
|
|
32
32
|
doc = [
|
|
33
33
|
"ansys-sphinx-theme==1.3.2",
|
|
34
34
|
"pdf2image==1.17.0",
|
|
35
|
-
"quarto-cli==1.
|
|
35
|
+
"quarto-cli==1.7.29",
|
|
36
36
|
"matplotlib==3.10.1",
|
|
37
37
|
"numpydoc==1.8.0",
|
|
38
38
|
"Sphinx==7.4.7",
|
|
@@ -41,8 +41,8 @@ doc = [
|
|
|
41
41
|
"sphinx-toggleprompt==0.6.0",
|
|
42
42
|
]
|
|
43
43
|
tests = [
|
|
44
|
-
"pytest==8.3.
|
|
45
|
-
"pytest-cov==6.
|
|
44
|
+
"pytest==8.3.5",
|
|
45
|
+
"pytest-cov==6.1.1",
|
|
46
46
|
"pytest-mock==3.14.0",
|
|
47
47
|
"pint==0.24.4",
|
|
48
48
|
]
|
|
@@ -30,20 +30,19 @@ __version__ = importlib_metadata.version(__name__.replace(".", "-"))
|
|
|
30
30
|
|
|
31
31
|
import os
|
|
32
32
|
|
|
33
|
-
from ansys.units.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
from ansys.units.base_dimensions import BaseDimensions
|
|
34
|
+
from ansys.units.dimensions import Dimensions
|
|
35
|
+
from ansys.units.quantity import Quantity, get_si_value
|
|
36
|
+
from ansys.units.quantity_dimensions import QuantityDimensions
|
|
37
|
+
from ansys.units.systems import UnitSystem
|
|
38
|
+
from ansys.units.unit import Unit
|
|
39
|
+
from ansys.units.unit_registry import UnitRegistry
|
|
40
|
+
from ansys.units.variable_descriptor import (
|
|
41
|
+
ConversionStrategy,
|
|
42
|
+
MappingConversionStrategy,
|
|
43
|
+
VariableCatalog,
|
|
44
|
+
VariableDescriptor,
|
|
40
45
|
)
|
|
41
|
-
from ansys.units.base_dimensions import BaseDimensions # noqa: F401
|
|
42
|
-
from ansys.units.dimensions import Dimensions # noqa: F401
|
|
43
|
-
from ansys.units.quantity import Quantity, get_si_value # noqa: F401
|
|
44
|
-
from ansys.units.systems import UnitSystem # noqa: F401
|
|
45
|
-
from ansys.units.unit import Unit # noqa: F401
|
|
46
|
-
from ansys.units.unit_registry import UnitRegistry # noqa: F401
|
|
47
46
|
|
|
48
47
|
_THIS_DIRNAME = os.path.dirname(__file__)
|
|
49
48
|
_README_FILE = os.path.normpath(os.path.join(_THIS_DIRNAME, "docs", "README.rst"))
|
|
@@ -51,3 +50,19 @@ _README_FILE = os.path.normpath(os.path.join(_THIS_DIRNAME, "docs", "README.rst"
|
|
|
51
50
|
if os.path.exists(_README_FILE):
|
|
52
51
|
with open(_README_FILE, encoding="utf8") as f:
|
|
53
52
|
__doc__ = f.read()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
__all__ = [
|
|
56
|
+
"BaseDimensions",
|
|
57
|
+
"Dimensions",
|
|
58
|
+
"Quantity",
|
|
59
|
+
"get_si_value",
|
|
60
|
+
"UnitSystem",
|
|
61
|
+
"Unit",
|
|
62
|
+
"UnitRegistry",
|
|
63
|
+
"QuantityDimensions",
|
|
64
|
+
"VariableDescriptor",
|
|
65
|
+
"VariableCatalog",
|
|
66
|
+
"ConversionStrategy",
|
|
67
|
+
"MappingConversionStrategy",
|
|
68
|
+
]
|
|
@@ -75,10 +75,7 @@ class Dimensions:
|
|
|
75
75
|
str
|
|
76
76
|
A string version of the dimensions.
|
|
77
77
|
"""
|
|
78
|
-
|
|
79
|
-
if not dims:
|
|
80
|
-
dims = ""
|
|
81
|
-
return str(dims)
|
|
78
|
+
return str({x.name: y for x, y in self})
|
|
82
79
|
|
|
83
80
|
def __str__(self):
|
|
84
81
|
return self._to_string()
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
#
|
|
5
|
+
#
|
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
# furnished to do so, subject to the following conditions:
|
|
12
|
+
#
|
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
# copies or substantial portions of the Software.
|
|
15
|
+
#
|
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
# SOFTWARE.
|
|
23
|
+
"""
|
|
24
|
+
Defines immutable objects representing SI base and derived physical dimensions.
|
|
25
|
+
|
|
26
|
+
This module provides globally defined `Dimensions` instances corresponding to the
|
|
27
|
+
seven SI base quantities (e.g., mass, time) and many commonly used derived quantities
|
|
28
|
+
(e.g., force, energy, pressure). These dimension definitions are used internally
|
|
29
|
+
for dimensional analysis, quantity construction, and validation.
|
|
30
|
+
|
|
31
|
+
Each dimension is represented as a `Dimensions` object, which captures the
|
|
32
|
+
dimensional exponents of base quantities such as mass, length, and time.
|
|
33
|
+
|
|
34
|
+
This module is not intended for direct modification at runtime. All objects
|
|
35
|
+
are statically defined and immutable.
|
|
36
|
+
|
|
37
|
+
Examples
|
|
38
|
+
--------
|
|
39
|
+
>>> from ansys.units.dimensions import Dimensions
|
|
40
|
+
>>> from ansys.units.quantity_dimensions import QuantityDimensions
|
|
41
|
+
|
|
42
|
+
>>> force = QuantityDimensions.FORCE
|
|
43
|
+
>>> pressure = QuantityDimensions.PRESSURE
|
|
44
|
+
>>> pressure == force / QuantityDimensions.AREA
|
|
45
|
+
True
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
from ansys.units.base_dimensions import BaseDimensions
|
|
49
|
+
from ansys.units.dimensions import Dimensions
|
|
50
|
+
|
|
51
|
+
# Local function to convert from a `BaseDimensions` enum object to a `Dimensions` object
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _make_base_dimensions(dimension: BaseDimensions) -> Dimensions:
|
|
55
|
+
return Dimensions(dimensions={dimension: 1.0})
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _expand_vector_quantities(cls):
|
|
59
|
+
angle = _make_base_dimensions(BaseDimensions.ANGLE)
|
|
60
|
+
for name in getattr(cls, "_vector_quantities", []):
|
|
61
|
+
value = getattr(cls, name)
|
|
62
|
+
# cartesian only added by default
|
|
63
|
+
setattr(cls, f"{name}_X", value)
|
|
64
|
+
setattr(cls, f"{name}_Y", value)
|
|
65
|
+
setattr(cls, f"{name}_Z", value)
|
|
66
|
+
# magnitude
|
|
67
|
+
setattr(cls, f"{name}_MAGNITUDE", value)
|
|
68
|
+
return cls
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@_expand_vector_quantities
|
|
72
|
+
class QuantityDimensions:
|
|
73
|
+
"""
|
|
74
|
+
Defines immutable dimension objects for standard physical quantities.
|
|
75
|
+
|
|
76
|
+
This class encapsulates SI base dimensions (e.g., MASS, TIME) and
|
|
77
|
+
commonly used derived dimensions (e.g., FORCE, PRESSURE, ENERGY),
|
|
78
|
+
using `Dimensions` instances.
|
|
79
|
+
|
|
80
|
+
These objects support arithmetic operations (multiplication, division,
|
|
81
|
+
exponentiation) to enable dimensional composition and analysis.
|
|
82
|
+
|
|
83
|
+
All attributes are class-level constants and should be treated as immutable.
|
|
84
|
+
|
|
85
|
+
Examples
|
|
86
|
+
--------
|
|
87
|
+
>>> QuantityDimensions.VELOCITY
|
|
88
|
+
Dimensions(dimensions={BaseDimensions.LENGTH: 1.0, BaseDimensions.TIME: -1.0})
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
# Dimensions of base quantities
|
|
92
|
+
MASS = _make_base_dimensions(BaseDimensions.MASS)
|
|
93
|
+
LENGTH = _make_base_dimensions(BaseDimensions.LENGTH)
|
|
94
|
+
TIME = _make_base_dimensions(BaseDimensions.TIME)
|
|
95
|
+
TEMPERATURE = _make_base_dimensions(BaseDimensions.TEMPERATURE)
|
|
96
|
+
CHEMICAL_AMOUNT = _make_base_dimensions(BaseDimensions.CHEMICAL_AMOUNT)
|
|
97
|
+
LIGHT = _make_base_dimensions(BaseDimensions.LIGHT)
|
|
98
|
+
CURRENT = _make_base_dimensions(BaseDimensions.CURRENT)
|
|
99
|
+
|
|
100
|
+
# Supplementary base quantities
|
|
101
|
+
ANGLE = _make_base_dimensions(BaseDimensions.ANGLE)
|
|
102
|
+
SOLID_ANGLE = _make_base_dimensions(BaseDimensions.SOLID_ANGLE)
|
|
103
|
+
TEMPERATURE_DIFFERENCE = _make_base_dimensions(
|
|
104
|
+
BaseDimensions.TEMPERATURE_DIFFERENCE
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# Dimensions of derived quantities
|
|
108
|
+
|
|
109
|
+
# Kinematics and mechanics
|
|
110
|
+
AREA = LENGTH**2
|
|
111
|
+
VOLUME = LENGTH**3
|
|
112
|
+
FREQUENCY = TIME**-1
|
|
113
|
+
VELOCITY = LENGTH / TIME
|
|
114
|
+
ACCELERATION = VELOCITY / TIME
|
|
115
|
+
FORCE = MASS * ACCELERATION
|
|
116
|
+
PRESSURE = FORCE / AREA
|
|
117
|
+
STRESS = PRESSURE
|
|
118
|
+
JERK = LENGTH / TIME**3
|
|
119
|
+
SNAP = LENGTH / TIME**4
|
|
120
|
+
ANGULAR_VELOCITY = TIME**-1
|
|
121
|
+
ANGULAR_ACCELERATION = TIME**-2
|
|
122
|
+
VOLUMETRIC_FLOW = VOLUME / TIME
|
|
123
|
+
MOMENTUM = MASS * VELOCITY
|
|
124
|
+
ANGULAR_MOMENTUM = LENGTH**2 * MASS / TIME
|
|
125
|
+
TORQUE = LENGTH**2 * MASS / TIME**2
|
|
126
|
+
ENERGY = LENGTH**2 * MASS / TIME**2
|
|
127
|
+
POWER = ENERGY / TIME
|
|
128
|
+
DENSITY = MASS / VOLUME
|
|
129
|
+
SPECIFIC_VOLUME = VOLUME / MASS
|
|
130
|
+
ENERGY_DENSITY = ENERGY / VOLUME
|
|
131
|
+
SURFACE_TENSION = FORCE / LENGTH
|
|
132
|
+
KINEMATIC_VISCOSITY = AREA / TIME
|
|
133
|
+
DYNAMIC_VISCOSITY = PRESSURE * TIME
|
|
134
|
+
MASS_FLOW_RATE = MASS / TIME
|
|
135
|
+
MASS_CONTROL = MASS / TIME**3
|
|
136
|
+
FREQUENCY_DRIFT = TIME**-2
|
|
137
|
+
YANK = FORCE / TIME
|
|
138
|
+
WAVENUMBER = LENGTH**-1
|
|
139
|
+
AREA_DENSITY = MASS / AREA
|
|
140
|
+
ACTION = ENERGY * TIME
|
|
141
|
+
SPECIFIC_ENERGY = ENERGY / MASS
|
|
142
|
+
HEAT_FLUX_DENSITY = POWER / AREA
|
|
143
|
+
SURFACE_HEAT_FLUX = HEAT_FLUX_DENSITY
|
|
144
|
+
LINEAR_MASS_DENSITY = MASS / LENGTH
|
|
145
|
+
RADIANCE = POWER / (SOLID_ANGLE * AREA)
|
|
146
|
+
SPECTRAL_POWER = POWER / LENGTH
|
|
147
|
+
ABSORBED_DOSE_RATE = AREA / TIME**3
|
|
148
|
+
FUEL_EFFICIENCY = LENGTH**-2
|
|
149
|
+
SPECTRAL_IRRADIANCE = POWER / VOLUME
|
|
150
|
+
ENERGY_FLUX_DENSITY = POWER / AREA
|
|
151
|
+
COMPRESSIBILITY = PRESSURE**-1
|
|
152
|
+
RADIANT_EXPOSURE = ENERGY / AREA
|
|
153
|
+
MOMENT_OF_INERTIA = MASS * AREA
|
|
154
|
+
SPECIFIC_ANGULAR_MOMENTUM = ANGULAR_MOMENTUM / MASS
|
|
155
|
+
RADIANT_INTENSITY = POWER / SOLID_ANGLE
|
|
156
|
+
SPECTRAL_INTENSITY = POWER / (SOLID_ANGLE * LENGTH)
|
|
157
|
+
STRAIN_RATE = TIME**-1
|
|
158
|
+
AXIAL_VELOCITY = VELOCITY
|
|
159
|
+
RADIAL_VELOCITY = VELOCITY
|
|
160
|
+
TANGENTIAL_VELOCITY = VELOCITY
|
|
161
|
+
|
|
162
|
+
# Electromagnetics
|
|
163
|
+
ELECTRIC_CHARGE = TIME * CURRENT
|
|
164
|
+
ELECTRICAL_POTENTIAL = MASS * AREA * TIME**-3 / CURRENT
|
|
165
|
+
ELECTRICAL_CAPACITANCE = MASS**-1 * LENGTH**-2 * TIME**4 * CURRENT**2
|
|
166
|
+
ELECTRICAL_INDUCTANCE = MASS * LENGTH**2 * TIME**-2 * CURRENT**-2
|
|
167
|
+
ELECTRICAL_RESISTANCE = ELECTRICAL_POTENTIAL / CURRENT
|
|
168
|
+
ELECTRICAL_IMPEDANCE = ELECTRICAL_RESISTANCE
|
|
169
|
+
ELECTRICAL_REACTANCE = ELECTRICAL_RESISTANCE
|
|
170
|
+
ELECTRICAL_CONDUCTANCE = ELECTRICAL_RESISTANCE**-1
|
|
171
|
+
MAGNETIC_FLUX = MASS * LENGTH**2 * TIME**-2 * CURRENT**-1
|
|
172
|
+
MAGNETIC_INDUCTION = MASS * TIME**-2 * CURRENT**-1
|
|
173
|
+
MAGNETIC_PERMEABILITY = LENGTH * MASS * TIME**-2 * CURRENT**-2
|
|
174
|
+
MAGNETIC_VECTOR_POTENTIAL = LENGTH * MASS * TIME**-2 * CURRENT**-1
|
|
175
|
+
|
|
176
|
+
# Chemistry
|
|
177
|
+
MOLARITY = CHEMICAL_AMOUNT / VOLUME
|
|
178
|
+
MOLAR_VOLUME = VOLUME / CHEMICAL_AMOUNT
|
|
179
|
+
MOLAR_HEAT_CAPACITY = ENERGY / (TEMPERATURE * CHEMICAL_AMOUNT)
|
|
180
|
+
MOLAR_ENTROPY = MOLAR_HEAT_CAPACITY
|
|
181
|
+
MOLAR_ENERGY = ENERGY / CHEMICAL_AMOUNT
|
|
182
|
+
MOLALITY = CHEMICAL_AMOUNT / MASS
|
|
183
|
+
MOLAR_MASS = MASS / CHEMICAL_AMOUNT
|
|
184
|
+
CATALYTIC_EFFICIENCY = VOLUME / (CHEMICAL_AMOUNT * TIME)
|
|
185
|
+
|
|
186
|
+
# Photometry
|
|
187
|
+
LUMINOUS_FLUX = LIGHT * SOLID_ANGLE
|
|
188
|
+
ILLUMINANCE = LUMINOUS_FLUX / AREA
|
|
189
|
+
LUMINANCE = LIGHT / AREA
|
|
190
|
+
LUMINOUS_EXPOSURE = ILLUMINANCE * TIME
|
|
191
|
+
|
|
192
|
+
# Thermodynamics
|
|
193
|
+
HEAT_CAPACITY = ENERGY / TEMPERATURE
|
|
194
|
+
SPECIFIC_HEAT_CAPACITY = HEAT_CAPACITY / MASS
|
|
195
|
+
THERMAL_CONDUCTIVITY = POWER / (LENGTH * TEMPERATURE)
|
|
196
|
+
THERMAL_RESISTANCE = TEMPERATURE / POWER
|
|
197
|
+
TEMPERATURE_GRADIENT = TEMPERATURE / LENGTH
|
|
198
|
+
ENTHALPY = ENERGY
|
|
199
|
+
ENTROPY = ENERGY / TEMPERATURE
|
|
200
|
+
SPECIFIC_ENTHALPY = ENTHALPY / MASS
|
|
201
|
+
SPECIFIC_ENTROPY = ENTROPY / MASS
|
|
202
|
+
INTERNAL_ENERGY = ENERGY
|
|
203
|
+
TOTAL_ENERGY = ENERGY
|
|
204
|
+
SPECIFIC_TOTAL_ENERGY = TOTAL_ENERGY / MASS
|
|
205
|
+
SPECIFIC_INTERNAL_ENERGY = INTERNAL_ENERGY / MASS
|
|
206
|
+
TOTAL_TEMPERATURE = TEMPERATURE
|
|
207
|
+
|
|
208
|
+
# Turbulence
|
|
209
|
+
PRANDTL_NUMBER = Dimensions()
|
|
210
|
+
EFFECTIVE_PRANDTL_NUMBER = Dimensions()
|
|
211
|
+
EFFECTIVE_THERMAL_CONDUCTIVITY = THERMAL_CONDUCTIVITY
|
|
212
|
+
EFFECTIVE_VISCOSITY = DYNAMIC_VISCOSITY
|
|
213
|
+
PRODUCTION_OF_TURBULENT_KINETIC_ENERGY = MASS * LENGTH**-1 * TIME**-3
|
|
214
|
+
SPECIFIC_DISSIPATION_RATE = TIME**-1
|
|
215
|
+
TURBULENT_DISSIPATION_RATE = LENGTH**2 * TIME**3
|
|
216
|
+
TURBULENT_INTENSITY = Dimensions()
|
|
217
|
+
TURBULENT_VISCOSITY = DYNAMIC_VISCOSITY
|
|
218
|
+
TURBULENT_VISCOSITY_RATIO = Dimensions()
|
|
219
|
+
TURBULENT_REYNOLDS_NUMBER = Dimensions()
|
|
220
|
+
TURBULENT_KINETIC_ENERGY = LENGTH**2 * TIME**-2
|
|
221
|
+
WALL_Y_PLUS = Dimensions()
|
|
222
|
+
WALL_Y_STAR = Dimensions()
|
|
223
|
+
|
|
224
|
+
# Fluid pressure
|
|
225
|
+
STATIC_PRESSURE = PRESSURE # equivalent
|
|
226
|
+
ABSOLUTE_PRESSURE = PRESSURE
|
|
227
|
+
DYNAMIC_PRESSURE = PRESSURE
|
|
228
|
+
TOTAL_PRESSURE = PRESSURE
|
|
229
|
+
PRESSURE_COEFFICIENT = Dimensions()
|
|
230
|
+
|
|
231
|
+
# Other fluid and related quantities
|
|
232
|
+
VORTICITY = TIME**-1
|
|
233
|
+
CONVECTIVE_COURANT_NUMBER = Dimensions()
|
|
234
|
+
CELL_REYNOLDS_NUMBER = Dimensions()
|
|
235
|
+
Q_CRITERION = TIME**-2
|
|
236
|
+
NORMALIZED_Q_CRITERION = Dimensions()
|
|
237
|
+
MESH_VELOCITY = VELOCITY
|
|
238
|
+
SPECIFIC_TOTAL_ENTHALPY = SPECIFIC_ENTHALPY
|
|
239
|
+
SURFACE_NUSSELT_NUMBER = Dimensions()
|
|
240
|
+
SURFACE_STANTON_NUMBER = Dimensions()
|
|
241
|
+
SKIN_FRICTION_COEFFICIENT = Dimensions()
|
|
242
|
+
SURFACE_HEAT_TRANSFER_COEFFICIENT = POWER * LENGTH**-2 * TEMPERATURE**-1
|
|
243
|
+
WALL_ADJACENT_HEAT_TRANSFER_COEFFICIENT = POWER * LENGTH**-2 * TEMPERATURE**-1
|
|
244
|
+
WALL_TEMPERATURE = TEMPERATURE
|
|
245
|
+
WALL_ADJACENT_TEMPERATURE = TEMPERATURE
|
|
246
|
+
WALL_TEMPERATURE_THIN = TEMPERATURE
|
|
247
|
+
WALL_SHEAR_STRESS = STRESS
|
|
248
|
+
|
|
249
|
+
# Coordinates
|
|
250
|
+
POSITION = LENGTH
|
|
251
|
+
|
|
252
|
+
# List of vector quantities. The only impact
|
|
253
|
+
# of not adding a vector quantity here is that
|
|
254
|
+
# the code will not autogenerate attributes
|
|
255
|
+
# <quantity>_X etc for that quantity.
|
|
256
|
+
_vector_quantities = [
|
|
257
|
+
"VELOCITY",
|
|
258
|
+
"ACCELERATION",
|
|
259
|
+
"VORTICITY",
|
|
260
|
+
"POSITION",
|
|
261
|
+
"MESH_VELOCITY",
|
|
262
|
+
"MOMENTUM",
|
|
263
|
+
"ANGULAR_MOMENTUM",
|
|
264
|
+
"TORQUE",
|
|
265
|
+
"FORCE",
|
|
266
|
+
"WALL_SHEAR_STRESS",
|
|
267
|
+
]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
"""
|
|
23
|
+
Package initialization for ansys.units.variable_descriptor.
|
|
24
|
+
|
|
25
|
+
Exports the VariableCatalog catalog and core interfaces for working with
|
|
26
|
+
physical quantities in a product-agnostic way.
|
|
27
|
+
|
|
28
|
+
Example
|
|
29
|
+
-------
|
|
30
|
+
|
|
31
|
+
.. code-block:: python
|
|
32
|
+
|
|
33
|
+
from ansys.units.variable_descriptor import VariableCatalog
|
|
34
|
+
from ansys.fluent.core.variable_strategies import FluentSVarNamingStrategy
|
|
35
|
+
|
|
36
|
+
quantity = VariableCatalog.PRESSURE
|
|
37
|
+
strategy = FluentSVarNamingStrategy()
|
|
38
|
+
|
|
39
|
+
print(strategy.to_string(quantity))
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
from .strategy import ConversionStrategy, MappingConversionStrategy
|
|
43
|
+
from .variable_descriptor import VariableCatalog, VariableDescriptor
|
|
44
|
+
|
|
45
|
+
__all__ = [
|
|
46
|
+
"VariableDescriptor",
|
|
47
|
+
"VariableCatalog",
|
|
48
|
+
"ConversionStrategy",
|
|
49
|
+
"MappingConversionStrategy",
|
|
50
|
+
]
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
"""
|
|
23
|
+
Defines the ConversionStrategy base class for translating `VariableDescriptor` objects.
|
|
24
|
+
|
|
25
|
+
Each concrete strategy maps `VariableDescriptor` instances to the string representations
|
|
26
|
+
required by a specific system.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from abc import ABC, abstractmethod
|
|
30
|
+
import types
|
|
31
|
+
|
|
32
|
+
from ansys.units.variable_descriptor.variable_descriptor import VariableDescriptor
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ConversionStrategy(ABC):
|
|
36
|
+
"""
|
|
37
|
+
Abstract base class for `VariableDescriptor` conversion strategies.
|
|
38
|
+
|
|
39
|
+
This class defines the interface for all conversion strategies. Derived classes
|
|
40
|
+
must implement the methods defined here to handle the conversion of `VariableDescriptor`
|
|
41
|
+
objects to and from their string representations, as well as to check if a
|
|
42
|
+
`VariableDescriptor` is supported.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
@abstractmethod
|
|
46
|
+
def to_string(self, variable: VariableDescriptor | str | None) -> str | None:
|
|
47
|
+
"""
|
|
48
|
+
Convert a `VariableDescriptor` to its string representation.
|
|
49
|
+
|
|
50
|
+
Parameters
|
|
51
|
+
----------
|
|
52
|
+
variable : VariableDescriptor | str
|
|
53
|
+
The `VariableDescriptor` to convert, or a string representation.
|
|
54
|
+
|
|
55
|
+
Returns
|
|
56
|
+
-------
|
|
57
|
+
str
|
|
58
|
+
The string representation of the `VariableDescriptor`.
|
|
59
|
+
|
|
60
|
+
Raises
|
|
61
|
+
------
|
|
62
|
+
NotImplementedError
|
|
63
|
+
If the method is not implemented in a derived class.
|
|
64
|
+
"""
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
@abstractmethod
|
|
68
|
+
def to_variable_descriptor(
|
|
69
|
+
self, variable: VariableDescriptor | str
|
|
70
|
+
) -> VariableDescriptor:
|
|
71
|
+
"""
|
|
72
|
+
Convert a string to its corresponding `VariableDescriptor`.
|
|
73
|
+
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
variable : VariableDescriptor | str
|
|
77
|
+
The string representation to convert, or a `VariableDescriptor`.
|
|
78
|
+
|
|
79
|
+
Returns
|
|
80
|
+
-------
|
|
81
|
+
VariableDescriptor
|
|
82
|
+
The corresponding `VariableDescriptor` instance.
|
|
83
|
+
|
|
84
|
+
Raises
|
|
85
|
+
------
|
|
86
|
+
NotImplementedError
|
|
87
|
+
If the method is not implemented in a derived class.
|
|
88
|
+
"""
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
@abstractmethod
|
|
92
|
+
def supports(self, variable: VariableDescriptor) -> bool:
|
|
93
|
+
"""
|
|
94
|
+
Check if the given `VariableDescriptor` is supported by the strategy.
|
|
95
|
+
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
variable : VariableDescriptor
|
|
99
|
+
The `VariableDescriptor` to check.
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
bool
|
|
104
|
+
`True` if the `VariableDescriptor` is supported, `False` otherwise.
|
|
105
|
+
|
|
106
|
+
Raises
|
|
107
|
+
------
|
|
108
|
+
NotImplementedError
|
|
109
|
+
If the method is not implemented in a derived class.
|
|
110
|
+
"""
|
|
111
|
+
pass
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class MappingConversionStrategy(ConversionStrategy):
|
|
115
|
+
"""
|
|
116
|
+
Intermediate base class for implementing VariableDescriptor conversion strategies.
|
|
117
|
+
|
|
118
|
+
This class simplifies the creation of concrete strategy classes by providing
|
|
119
|
+
default implementations for common methods. Classes inheriting from this base
|
|
120
|
+
class only need to define a `_mapping` dictionary that maps `VariableDescriptor`
|
|
121
|
+
instances to their corresponding string representations.
|
|
122
|
+
|
|
123
|
+
Attributes
|
|
124
|
+
----------
|
|
125
|
+
_reverse_mapping : dict
|
|
126
|
+
A lazily initialized reverse mapping of `_mapping`, used for converting
|
|
127
|
+
strings back to `VariableDescriptor` instances.
|
|
128
|
+
|
|
129
|
+
Methods
|
|
130
|
+
-------
|
|
131
|
+
to_string(variable: VariableDescriptor | str) -> str
|
|
132
|
+
Converts a `VariableDescriptor` to its string representation. Raises a
|
|
133
|
+
`ValueError` if the variable is not supported.
|
|
134
|
+
to_variable_descriptor(variable: VariableDescriptor | str) -> VariableDescriptor
|
|
135
|
+
Converts a string to its corresponding `VariableDescriptor`.
|
|
136
|
+
supports(variable: VariableDescriptor) -> bool
|
|
137
|
+
Checks if the given `VariableDescriptor` is supported by the strategy.
|
|
138
|
+
|
|
139
|
+
Raises
|
|
140
|
+
------
|
|
141
|
+
ValueError
|
|
142
|
+
If a `VariableDescriptor` is not supported during conversion to a string.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
def __init__(self):
|
|
146
|
+
"""
|
|
147
|
+
Initialize the MappingConversionStrategy.
|
|
148
|
+
|
|
149
|
+
This constructor initializes the reverse mapping attribute to `None`.
|
|
150
|
+
The reverse mapping is lazily initialized when accessed via the `_reverse_mapping` property.
|
|
151
|
+
"""
|
|
152
|
+
self.__reverse_mapping = None
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def _reverse_mapping(self):
|
|
156
|
+
"""
|
|
157
|
+
Get the reverse mapping of `_mapping`.
|
|
158
|
+
|
|
159
|
+
The reverse mapping is a dictionary that maps string representations
|
|
160
|
+
back to their corresponding `VariableDescriptor` instances. It is lazily
|
|
161
|
+
initialized on first access.
|
|
162
|
+
|
|
163
|
+
Returns
|
|
164
|
+
-------
|
|
165
|
+
dict
|
|
166
|
+
A dictionary mapping string representations to `VariableDescriptor` instances.
|
|
167
|
+
"""
|
|
168
|
+
if self.__reverse_mapping is None:
|
|
169
|
+
self.__reverse_mapping = {x: y for y, x in self._mapping.items()}
|
|
170
|
+
return self.__reverse_mapping
|
|
171
|
+
|
|
172
|
+
def to_string(self, variable: VariableDescriptor | str | None) -> str | None:
|
|
173
|
+
"""
|
|
174
|
+
Convert a `VariableDescriptor` to its string representation.
|
|
175
|
+
|
|
176
|
+
If the input is already a string, it is returned as-is. If the input
|
|
177
|
+
is a `VariableDescriptor` and is supported by the strategy, its string
|
|
178
|
+
representation is returned. Otherwise, a `ValueError` is raised.
|
|
179
|
+
|
|
180
|
+
Parameters
|
|
181
|
+
----------
|
|
182
|
+
variable : VariableDescriptor | str
|
|
183
|
+
The `VariableDescriptor` to convert, or a string representation.
|
|
184
|
+
|
|
185
|
+
Returns
|
|
186
|
+
-------
|
|
187
|
+
str
|
|
188
|
+
The string representation of the `VariableDescriptor`.
|
|
189
|
+
|
|
190
|
+
Raises
|
|
191
|
+
------
|
|
192
|
+
ValueError
|
|
193
|
+
If the `VariableDescriptor` is not supported by the strategy.
|
|
194
|
+
"""
|
|
195
|
+
if isinstance(variable, (str, types.NoneType)):
|
|
196
|
+
return variable
|
|
197
|
+
if not self.supports(variable):
|
|
198
|
+
raise ValueError(f"{variable.name} not supported.")
|
|
199
|
+
return self._mapping[variable]
|
|
200
|
+
|
|
201
|
+
def to_variable_descriptor(
|
|
202
|
+
self, variable: VariableDescriptor | str
|
|
203
|
+
) -> VariableDescriptor:
|
|
204
|
+
"""
|
|
205
|
+
Convert a string to its corresponding `VariableDescriptor`.
|
|
206
|
+
|
|
207
|
+
If the input is already a `VariableDescriptor`, it is returned as-is.
|
|
208
|
+
Otherwise, the string is converted to a `VariableDescriptor` using the
|
|
209
|
+
reverse mapping.
|
|
210
|
+
|
|
211
|
+
Parameters
|
|
212
|
+
----------
|
|
213
|
+
variable : VariableDescriptor | str
|
|
214
|
+
The string representation to convert, or a `VariableDescriptor`.
|
|
215
|
+
|
|
216
|
+
Returns
|
|
217
|
+
-------
|
|
218
|
+
VariableDescriptor
|
|
219
|
+
The corresponding `VariableDescriptor` instance, or `None` if the
|
|
220
|
+
string is not found in the reverse mapping.
|
|
221
|
+
"""
|
|
222
|
+
if isinstance(variable, VariableDescriptor):
|
|
223
|
+
return variable
|
|
224
|
+
return self._reverse_mapping.get(variable)
|
|
225
|
+
|
|
226
|
+
def supports(self, variable: VariableDescriptor) -> bool:
|
|
227
|
+
"""
|
|
228
|
+
Check if the given `VariableDescriptor` is supported by the strategy.
|
|
229
|
+
|
|
230
|
+
Parameters
|
|
231
|
+
----------
|
|
232
|
+
variable : VariableDescriptor
|
|
233
|
+
The `VariableDescriptor` to check.
|
|
234
|
+
|
|
235
|
+
Returns
|
|
236
|
+
-------
|
|
237
|
+
bool
|
|
238
|
+
`True` if the `VariableDescriptor` is supported, `False` otherwise.
|
|
239
|
+
"""
|
|
240
|
+
return variable in self._mapping
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
"""
|
|
23
|
+
Defines the core VariableDescriptor class and predefined quantities.
|
|
24
|
+
|
|
25
|
+
This module provides a structured, extensible way to represent variables based on
|
|
26
|
+
physical quantities (e.g., pressure, velocity) independently of any product-specific
|
|
27
|
+
naming conventions.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
from dataclasses import dataclass
|
|
31
|
+
|
|
32
|
+
from ansys.units.dimensions import Dimensions
|
|
33
|
+
from ansys.units.quantity_dimensions import QuantityDimensions
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(frozen=True)
|
|
37
|
+
class VariableDescriptor:
|
|
38
|
+
"""Defines a physical quantity variable descriptor."""
|
|
39
|
+
|
|
40
|
+
name: str
|
|
41
|
+
dimension: Dimensions
|
|
42
|
+
|
|
43
|
+
def __hash__(self):
|
|
44
|
+
return hash((self.name, str(self.dimension)))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _validate_and_transform_variable(variable: str) -> str:
|
|
48
|
+
"""
|
|
49
|
+
Validate and transform a variable name.
|
|
50
|
+
|
|
51
|
+
Ensures the variable name is uppercase and returns its lowercase equivalent.
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
variable : str
|
|
56
|
+
The name of the variable.
|
|
57
|
+
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
str
|
|
61
|
+
The lowercase equivalent of the variable name.
|
|
62
|
+
|
|
63
|
+
Raises
|
|
64
|
+
------
|
|
65
|
+
ValueError
|
|
66
|
+
If the variable name is not uppercase.
|
|
67
|
+
"""
|
|
68
|
+
if not variable.isupper():
|
|
69
|
+
raise ValueError(
|
|
70
|
+
f"Variable names in VariableCatalog must be uppercase. "
|
|
71
|
+
f"Invalid name: '{variable}'."
|
|
72
|
+
)
|
|
73
|
+
return variable.lower()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _build_variable_descriptors_from_dimensions() -> dict[str, VariableDescriptor]:
|
|
77
|
+
"""
|
|
78
|
+
Generate a dictionary of variable descriptors from QuantityDimensions.
|
|
79
|
+
|
|
80
|
+
This function iterates over all uppercase attributes in QuantityDimensions and
|
|
81
|
+
creates VariableDescriptor instances for each valid dimension.
|
|
82
|
+
"""
|
|
83
|
+
catalog = {}
|
|
84
|
+
for attr_name in dir(QuantityDimensions):
|
|
85
|
+
dimension = getattr(QuantityDimensions, attr_name)
|
|
86
|
+
if isinstance(dimension, Dimensions):
|
|
87
|
+
catalog[attr_name] = VariableDescriptor(
|
|
88
|
+
name=_validate_and_transform_variable(attr_name), dimension=dimension
|
|
89
|
+
)
|
|
90
|
+
return catalog
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class VariableCatalog:
|
|
94
|
+
"""A catalog of variable descriptors."""
|
|
95
|
+
|
|
96
|
+
# Load from generator
|
|
97
|
+
_generated = _build_variable_descriptors_from_dimensions()
|
|
98
|
+
|
|
99
|
+
# Inject generated descriptors as class attributes
|
|
100
|
+
for _key, _descriptor in _generated.items():
|
|
101
|
+
locals()[_key] = _descriptor
|
|
102
|
+
|
|
103
|
+
@classmethod
|
|
104
|
+
def all(cls) -> dict[str, list[VariableDescriptor]]:
|
|
105
|
+
"""
|
|
106
|
+
Return all defined
|
|
107
|
+
:class:`~ansys.units.variable_descriptor.variable_descriptor.VariableDescriptor`
|
|
108
|
+
objects, organized by subcategory.
|
|
109
|
+
|
|
110
|
+
Returns
|
|
111
|
+
-------
|
|
112
|
+
dict[str, list[VariableDescriptor]]
|
|
113
|
+
A dictionary where keys are subcategory names (or "main" for the top-level catalog)
|
|
114
|
+
and values are lists of :class:`~ansys.units.variable_descriptor.variable_descriptor.VariableDescriptor` instances.
|
|
115
|
+
""" # noqa: E501
|
|
116
|
+
result = {"main": []}
|
|
117
|
+
|
|
118
|
+
for key, value in cls.__dict__.items():
|
|
119
|
+
if isinstance(value, VariableDescriptor):
|
|
120
|
+
result["main"].append(value)
|
|
121
|
+
elif (
|
|
122
|
+
isinstance(value, type)
|
|
123
|
+
and issubclass(value, object)
|
|
124
|
+
and value is not object
|
|
125
|
+
):
|
|
126
|
+
# Collect descriptors from subcategories
|
|
127
|
+
subcategory_name = key
|
|
128
|
+
result[subcategory_name] = [
|
|
129
|
+
v
|
|
130
|
+
for k, v in value.__dict__.items()
|
|
131
|
+
if isinstance(v, VariableDescriptor)
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
return result
|
|
135
|
+
|
|
136
|
+
@classmethod
|
|
137
|
+
def add(
|
|
138
|
+
cls, variable: str, dimension: Dimensions, subcategory: str | None = None
|
|
139
|
+
) -> None:
|
|
140
|
+
"""
|
|
141
|
+
Add a variable to the catalog.
|
|
142
|
+
|
|
143
|
+
Parameters
|
|
144
|
+
----------
|
|
145
|
+
variable : str
|
|
146
|
+
The name of the variable (must be uppercase).
|
|
147
|
+
dimension : Dimensions
|
|
148
|
+
The dimension of the variable.
|
|
149
|
+
subcategory: str|None
|
|
150
|
+
The optional subcategory for the variable.
|
|
151
|
+
|
|
152
|
+
Raises
|
|
153
|
+
------
|
|
154
|
+
ValueError
|
|
155
|
+
The variable name is not uppercase or already exists.
|
|
156
|
+
"""
|
|
157
|
+
# Validate and transform the variable name
|
|
158
|
+
transformed_name = _validate_and_transform_variable(variable)
|
|
159
|
+
|
|
160
|
+
# Determine the target category (main catalog or subcategory)
|
|
161
|
+
target = cls
|
|
162
|
+
if subcategory:
|
|
163
|
+
# Ensure the subcategory exists as an attribute
|
|
164
|
+
if not hasattr(cls, subcategory):
|
|
165
|
+
# Create the subcategory and assign a docstring
|
|
166
|
+
subcategory_class = type(
|
|
167
|
+
subcategory,
|
|
168
|
+
(object,),
|
|
169
|
+
{
|
|
170
|
+
"__doc__": (
|
|
171
|
+
f"Dictionary of variable descriptors for {subcategory}-related "
|
|
172
|
+
f"quantities."
|
|
173
|
+
)
|
|
174
|
+
},
|
|
175
|
+
)
|
|
176
|
+
setattr(cls, subcategory, subcategory_class)
|
|
177
|
+
target = getattr(cls, subcategory)
|
|
178
|
+
|
|
179
|
+
# Check if the variable already exists in the target category
|
|
180
|
+
if hasattr(target, variable):
|
|
181
|
+
raise ValueError(
|
|
182
|
+
f"Variable name '{variable}' already exists in the '{subcategory or 'main'}' "
|
|
183
|
+
"catalog. Please choose a unique name."
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# Add the variable to the target category
|
|
187
|
+
setattr(target, variable, VariableDescriptor(transformed_name, dimension))
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
# Add custom descriptors
|
|
191
|
+
_D = QuantityDimensions
|
|
192
|
+
fluent_variables = [
|
|
193
|
+
# velocity
|
|
194
|
+
# The dominant meaning of helicity comes from
|
|
195
|
+
# particle physics where it is dimensionless.
|
|
196
|
+
# In CFD, where it has a different
|
|
197
|
+
# meaning, it usually has dimension L^2 T^-2.
|
|
198
|
+
# In Fluent it is L T^-2.
|
|
199
|
+
("HELICITY", _D.ACCELERATION),
|
|
200
|
+
# Lambda 2 criterion is documented as dimensionless
|
|
201
|
+
# but is T^-2 in Fluent.
|
|
202
|
+
("LAMBDA_2_CRITERION", _D.TIME**-2),
|
|
203
|
+
("DENSITY_ALL", _D.DENSITY),
|
|
204
|
+
(
|
|
205
|
+
"Y_PLUS_BASED_HEAT_TRANSFER_COEFFICIENT",
|
|
206
|
+
_D.POWER * _D.LENGTH**-2 * _D.TEMPERATURE**-1,
|
|
207
|
+
),
|
|
208
|
+
("TOTAL_ENTHALPY_DEVIATION", _D.SPECIFIC_ENTHALPY),
|
|
209
|
+
# residuals
|
|
210
|
+
("MASS_IMBALANCE", _D.MASS * _D.TIME**-1),
|
|
211
|
+
# derivatives
|
|
212
|
+
("PRESSURE_HESSIAN_INDICATOR", Dimensions()),
|
|
213
|
+
("VELOCITY_ANGLE", _D.ANGLE),
|
|
214
|
+
("DVELOCITY_DX", _D.TIME**-1),
|
|
215
|
+
("DVELOCITY_DX_MAGNITUDE", _D.TIME**-1),
|
|
216
|
+
("DVELOCITY_DX_X", _D.TIME**-1),
|
|
217
|
+
("DVELOCITY_DX_Y", _D.TIME**-1),
|
|
218
|
+
("DVELOCITY_DX_Z", _D.TIME**-1),
|
|
219
|
+
("DVELOCITY_DY", _D.TIME**-1),
|
|
220
|
+
("DVELOCITY_DY_MAGNITUDE", _D.TIME**-1),
|
|
221
|
+
("DVELOCITY_DY_X", _D.TIME**-1),
|
|
222
|
+
("DVELOCITY_DY_Y", _D.TIME**-1),
|
|
223
|
+
("DVELOCITY_DY_Z", _D.TIME**-1),
|
|
224
|
+
("DVELOCITY_DZ", _D.TIME**-1),
|
|
225
|
+
("DVELOCITY_DZ_MAGNITUDE", _D.TIME**-1),
|
|
226
|
+
("DVELOCITY_DZ_X", _D.TIME**-1),
|
|
227
|
+
("DVELOCITY_DZ_Y", _D.TIME**-1),
|
|
228
|
+
("DVELOCITY_DZ_Z", _D.TIME**-1),
|
|
229
|
+
]
|
|
230
|
+
|
|
231
|
+
for name, dimension in fluent_variables:
|
|
232
|
+
VariableCatalog.add(name, dimension, "fluent")
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
mesh_variables = [
|
|
236
|
+
# mesh
|
|
237
|
+
("ANISOTROPIC_ADAPTION_CELLS", Dimensions()),
|
|
238
|
+
("BOUNDARY_CELL_DISTANCE", Dimensions()),
|
|
239
|
+
("BOUNDARY_LAYER_CELLS", Dimensions()),
|
|
240
|
+
("BOUNDARY_NORMAL_DISTANCE", Dimensions()),
|
|
241
|
+
("BOUNDARY_VOLUME_DISTANCE", Dimensions()),
|
|
242
|
+
("CELL_EQUIANGLE_SKEW", Dimensions()),
|
|
243
|
+
("CELL_EQUIVOLUME_SKEW", Dimensions()),
|
|
244
|
+
("CELL_PARENT_INDEX", Dimensions()),
|
|
245
|
+
("CELL_REFINE_LEVEL", Dimensions()),
|
|
246
|
+
("CELL_VOLUME", _D.VOLUME),
|
|
247
|
+
("CELL_VOLUME_CHANGE", Dimensions()),
|
|
248
|
+
("ELEMENT_ASPECT_RATIO", Dimensions()),
|
|
249
|
+
("ELEMENT_WALL_DISTANCE", _D.LENGTH),
|
|
250
|
+
("FACE_AREA_MAGNITUDE", _D.AREA),
|
|
251
|
+
("FACE_HANDEDNESS", Dimensions()),
|
|
252
|
+
("INTERFACE_OVERLAP_FRACTION", Dimensions()),
|
|
253
|
+
("MARK_POOR_ELEMENTS", Dimensions()),
|
|
254
|
+
("SMOOTHED_CELL_REFINE_LEVEL", Dimensions()),
|
|
255
|
+
("X_FACE_AREA", _D.AREA),
|
|
256
|
+
("Y_FACE_AREA", _D.AREA),
|
|
257
|
+
("Z_FACE_AREA", _D.AREA),
|
|
258
|
+
# cell info
|
|
259
|
+
("ACTIVE_CELL_PARTITION", Dimensions()),
|
|
260
|
+
("CELL_ELEMENT_TYPE", Dimensions()),
|
|
261
|
+
("CELL_ID", Dimensions()),
|
|
262
|
+
("CELL_WEIGHT", Dimensions()),
|
|
263
|
+
("CELL_ZONE_INDEX", Dimensions()),
|
|
264
|
+
("CELL_ZONE_TYPE", Dimensions()),
|
|
265
|
+
("PARTITION_NEIGHBOURS", Dimensions()),
|
|
266
|
+
("STORED_CELL_PARTITIION", Dimensions()),
|
|
267
|
+
]
|
|
268
|
+
|
|
269
|
+
for name, dimension in mesh_variables:
|
|
270
|
+
VariableCatalog.add(name, dimension, "mesh")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ansys_units-0.5.dev0 → ansys_units-0.6.dev0}/src/ansys/units/quantity_tables/cgs_table.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|