Skip to content

Proposal to Support VariableCatalog from PyAnsys-Units #3939

Open
@seanpearsonuk

Description

@seanpearsonuk

Description of the feature

Variable Descriptors

The ansys.units.variable_descriptor subpackage defines interfaces and implementations for representing physical quantities in a product-agnostic, unit-aware way. These descriptors serve as the foundation for communicating quantity metadata across Ansys systems and external APIs.

Overview

A VariableDescriptor encapsulates information about a physical quantity, such as:

  • Its name (for example, VELOCITY, FORCE)

  • Its associated dimensionality (via QuantityDimensions)

  • Optional metadata for display, categorization, or mapping to domain-specific naming schemes

These descriptors are immutable and hashable, making them suitable as keys in mappings and registries.

The subpackage also defines conversion strategies that translate between VariableDescriptor objects and external string representations (such as Fluent variable names).

Note: We are currently in the process of fully releasing the feature.

Current Usage in PyFluent

Usage is demonstrated in PyFluent unit-tests. Note that we have demonstrated use for five Fluent/PyFluent interfaces which span three separate naming conventions

from ansys.units.variable_descriptor import VariableCatalog
temperature = VariableCatalog.TEMPERATURE
# Ordinarily, field_name must be a string
temperature_field_data = fields.field_data.get_scalar_field_data(
    field_name=temperature, surfaces=locations
)

Proposed Usage in PyMAPDL

Here's a snippet from a current script.

mapdl.mp("DENS", 1, 2550)  # density
mapdl.mp("ALPX", 1, 1.2e-05)  # thermal expansion coefficient
mapdl.mp("EX", 1, 2500000)  # Young's modulus
mapdl.mp("NUXY", 1, 0.35)  # Poisson's ratio

Here's what the transformed script would look like.

from ansys.units.variable_descriptor import VariableCatalog as vars
mapdl.mp(vars.DENSITY, 1, 2550)  # density
mapdl.mp(vars.THERMAL_EXPANSION_COEFFICIENT, 1, 1.2e-05)  # thermal expansion coefficient
mapdl.mp(vars.YOUNG_MODULUS, 1, 2500000)  # Young's modulus
mapdl.mp(vars.POISSON_RATIO, 1, 0.35)  # Poisson's ratio

All the above catalog attributes are available now--they simply need to be mapped to PyMADPL string values.

Steps for implementing the feature

  1. Define an MAPDL naming strategy. Fluent defines three separate ones, reflecting the different Fluent naming conventions. A strategy for PyMAPDL would have a similar structure to the one shown here. The keys of the _mapping dict would be selected from the VariableCatalog to reflect variables actually supported by MAPDL while the mapped values would be the actual MAPDL names for the variables.
  from ansys.units.variable_descriptor import (
      MappingConversionStrategy,
      VariableCatalog,
  )

  class FluentFieldDataNamingStrategy(MappingConversionStrategy):
      """This strategy handles conversion of selected
      VariableCatalog into Fluent's server-side field variable naming conventions.
      """

      _c = VariableCatalog

      # I have edited this dictionary to make it smaller for illustration
      _mapping = {
          _c.PRESSURE: "pressure",
          _c.VELOCITY: "velocity",
          _c.VELOCITY_X: "x-velocity",
          _c.DENSITY: "density",
          _c.SPECIFIC_HEAT_CAPACITY: "specific-heat-cp",
          _c.THERMAL_CONDUCTIVITY: "thermal-conductivity",
          _c.TURBULENT_INTENSITY: "turb-intensity",
          _c.SURFACE_HEAT_TRANSFER_COEFFICIENT: "heat-transfer-coef",
      }
  1. Integrate the new strategy into the PyMAPDL API code. This is an example of how it's done in PyFluent.
from ansys.fluent.core.variable_strategies import (
    FluentExprNamingStrategy as naming_strategy,
)
# ...
def __init__(self, ...):
    """__init__ method of Reduction class."""
    # ...
    self._to_str = naming_strategy().to_string

def _make_request(self, ...) -> Any:
    # ...
    # Here, `expression` can be any one of (i) a mathematical expression
    # string, (ii) a variable name string, or (iii) an entry from the `VariableCatalog`.
    # In the case of (i) or (ii) the original string is simply returned. Unsupported
    # catalog entries trigger a `ValueError`.
    if expression is not None:
        request.expression = self._to_str(expression)

Useful links and references

https://github.com/ansys/pyansys-units/blob/main/src/ansys/units/quantity_dimensions.py
https://github.com/ansys/pyansys-units/tree/main/src/ansys/units/variable_descriptor
https://github.com/ansys/pyansys-units/blob/main/doc/source/user_guide/quantity_dimensions.rst
https://github.com/ansys/pyansys-units/blob/main/doc/source/user_guide/variable_descriptor.rst
https://github.com/ansys/pyfluent/blob/main/doc/source/user_guide/physical_variables.rst
https://github.com/ansys/pyfluent/tree/main/src/ansys/fluent/core/variable_strategies
https://github.com/ansys/pyfluent/tree/main/src/ansys/fluent/core/services
https://github.com/ansys/pyfluent/blob/main/tests/test_physical_quantities.py

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementImprove any current implemented feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions