The active_path.py module#
Summary#
A snapshot of the live solver mode facets that gate path selection. |
|
Classification of a concrete path within a multi-path group. |
|
Result of checking a proposed path against the live mode. |
|
Canonical resolution of “where should a write to |
Return True for coupled-family pressure-velocity schemes (hyphen-tolerant). |
|
Return the URF family that is ACTIVE under |
|
Return the ACTIVE concrete URF path for |
|
Classify |
|
Check |
|
Return the |
|
Active boundary-condition namespace root. |
|
Active cell-zone namespace root. |
|
Active mesh-interface namespace root. |
|
Active indexed BC node path (e.g. |
|
Active indexed cell-zone node path. |
|
Active run-calculation command path (steady vs transient). |
|
Per-phase BC volume-fraction path under the active namespace. |
|
Return the per-phase BC leaf path under the active namespace. |
|
Return |
|
Return the canonical |
|
Return a compact JSON-safe summary of |
|
Return canonical write-target answers for the CURRENT |
|
Return a short human-readable summary of |
Description#
Active-path resolver — one deterministic primitive for mode-dependent paths.
Fluent exposes the same logical setting at MULTIPLE physical paths whose
ACTIVE one depends on the live solver mode. Writing the wrong sibling is
silently rejected (InactiveObjectError / “the object cannot be edited”).
The canonical example is under-relaxation factors (URFs), whose family
depends on the pressure-velocity coupling scheme:
segregated (SIMPLE / SIMPLEC / PISO / Fractional Step) ->
solution.controls.under_relaxation['(a NamedObject family)'] coupled, no pseudo-transient ->
solution.controls.p_v_controls.explicit_*_under_relaxation(scalars) +solution.controls.relaxation_factor[''] coupled + pseudo-transient ->
solution.controls.pseudo_time_explicit_relaxation_factor .global_dt_pseudo_relax['']
Historically this knowledge was scattered across recipe URF stagers
(stage_under_relaxation_auto), the agent resolve_active_path tool,
the validator’s inactive_path diagnostic, and per-recipe is_utl
branches. This module is the SINGLE source of truth, shared by the OSS
leaf and the agent monorepo.
Two cooperating capabilities:
Forward resolution – given a
SolverMode+ a logical setting (e.g. a URF equation, a BC family/name, the run command), return the concrete active path. Seeurf_path(),bc_path(),run_calculation_path(), …Reverse routing – given ANY proposed path + a
SolverMode, say whether it is active and, if not, what the correct active sibling is. Seereroute(). This is what lets the validator hard-block a wrong-path write before Apply and hand clients a deterministic fix instead of letting the executor silently skip the step.
The module has NO dependency on the agent loop or live backend; it is pure,
deterministic Fluent-path knowledge. Build the SolverMode from a
live state snapshot (SolverMode.from_state()) and pass it in.
Module detail#
- active_path.is_coupled_scheme(flow_scheme: str | None) bool#
Return True for coupled-family pressure-velocity schemes (hyphen-tolerant).
- active_path.active_urf_family(mode: SolverMode) UrfFamily#
Return the URF family that is ACTIVE under
mode.coupled + pseudo-transient -> per-equation pseudo-time family
coupled (no pseudo) -> explicit scalar + relaxation_factor
segregated -> under_relaxation NamedObject family
- active_path.urf_path(mode: SolverMode, equation: str) str#
Return the ACTIVE concrete URF path for
equationundermode.Examples
>>> urf_path(SolverMode(), "pressure") "solution.controls.under_relaxation['pressure']" >>> urf_path(SolverMode(flow_scheme="Coupled"), "momentum") 'solution.controls.p_v_controls.explicit_momentum_under_relaxation' >>> urf_path(SolverMode(flow_scheme="Coupled", pseudo_transient=True), "k") "solution.controls.pseudo_time_explicit_relaxation_factor.global_dt_pseudo_relax['k']"
- active_path.classify_path(path: str) PathInfo | None#
Classify
pathinto a known multi-path group, orNone.Nonemeans the path is not a known mode-dependent setting, so callers should treat it as “we can’t reason about activation here” and NOT block it.
- active_path.reroute(path: str, mode: SolverMode) RerouteResult#
Check
pathagainstmodeand, if inactive, point to the fix.Deterministic and conservative: returns
active=Truefor any path that is not a recognized multi-path setting, so it never false-blocks an ordinary write.
- active_path.path_family(mode: SolverMode) ansys.fluent.mcp.solve.lib.utl.PathFamily#
Return the
PathFamilytranslator formode.
- active_path.bc_root(mode: SolverMode) str#
Active boundary-condition namespace root.
- active_path.cz_root(mode: SolverMode) str#
Active cell-zone namespace root.
- active_path.interface_root(mode: SolverMode) str#
Active mesh-interface namespace root.
- active_path.bc_path(mode: SolverMode, family: str, name: str) str#
Active indexed BC node path (e.g.
...wall['hw']).
- active_path.cz_path(mode: SolverMode, family: str, name: str) str#
Active indexed cell-zone node path.
- active_path.run_calculation_path(mode: SolverMode) str#
Active run-calculation command path (steady vs transient).
- active_path.multiphase_volume_fraction_path(mode: SolverMode, bc_family: str, bc_name: str, phase_key: str, *, leaf: str = 'volume_fraction') str#
Per-phase BC volume-fraction path under the active namespace.
leafdefaults to the inletvolume_fractionvalue leaf; pass a different scoped leaf (e.g.backflow_volume_fraction) as needed. Kept for backward compatibility; new callers should prefer the more generalmultiphase_bc_phase_path().
- active_path.multiphase_bc_phase_path(mode: SolverMode, bc_family: str, bc_name: str, phase_key: str, *, leaf: str, scope: str = 'multiphase', value_suffix: bool = True) str#
Return the per-phase BC leaf path under the active namespace.
On multiphase cases Fluent splits BC leaves into two tiers:
Mixture-level leaves (
momentum.*,turbulence.*,dpm.*, …) live directly on the BC’s top namespace and are set once per BC — callbc_path()for those.Per-phase leaves (
volume_fraction,granular_temperature, per-phase turbulence / DPM / species knobs, …) live underphase['on the BC. Writing them under a NON-matching phase key is silently rejected.']. .
This helper composes the per-phase path for ANY leaf (not just
volume_fractionas the legacy helper did) so multiphase-aware callers do not need to string-format the path themselves. It also handles the.valuesuffix that Fluent applies to numeric leaves (volume_fraction.value) while allowing structural leaves that do NOT carry the suffix (turbulence.turb_intensity) viavalue_suffix=False.- Parameters:
- mode
Live solver mode (drives UTL vs standard root selection).
- bc_family
BC family (e.g.
"velocity_inlet","pressure_outlet","mass_flow_inlet","wall").- bc_name
Named-object key on the BC family (e.g.
"inlet1").- phase_key
Phase-name key as stored on
setup.models.multiphase.phases(typically a user-visible string like"water-liquid"or Fluent’s default"phase-1").- leaf
The per-phase leaf name relative to
(e.g."volume_fraction","granular_temperature","turb_intensity","backflow_volume_fraction").- scope
Container under which the leaf lives on the phase branch; Fluent uses
"multiphase"for VOF / mixture / eulerian volume-fraction / granular knobs (the default). Turbulence per-phase leaves live under"turbulence"; DPM per-phase under"dpm".- value_suffix
Append
.valueto the path. True for numeric quantities (the common case), False for structural / enum leaves.
- Returns:
strThe concrete active per-phase BC path.
Examples
>>> multiphase_bc_phase_path( ... SolverMode(), ... "velocity_inlet", ... "inlet1", ... "water-liquid", ... leaf="volume_fraction", ... ) "setup.boundary_conditions.velocity_inlet['inlet1'].phase['water-liquid'].multiphase.volume_fraction.value"
>>> multiphase_bc_phase_path( ... SolverMode(utl=True), ... "wall", ... "hw", ... "primary", ... leaf="turb_intensity", ... scope="turbulence", ... value_suffix=False, ... ) "setup.physics.boundaries.wall['hw'].phase['primary'].turbulence.turb_intensity"
- active_path.classify_methods_gate(path: str) tuple[str, str] | None#
Return
(facet_name, human_description)for a mode-gated methods prefix.If
pathstarts with a knownsolution.methods.*mode-gated prefix, return the facet + description tuple; otherwise returnNone.Consumers should call
_methods_facet_active()(or replicate its logic) to decide whether the gate is currently satisfied. This is complementary toclassify_path()— the latter handles URF / BC / CZ / interface / run families and returns aPathInfo; this helper coverssolution.methods.*where the “correct sibling” concept does not apply (the path is either active or the mode is wrong).
- active_path.resolve_write_target(mode: SolverMode, path: str) WriteTarget#
Return the canonical
WriteTargetfor a proposed write.Combines
classify_path()+reroute()(multi-path families) withclassify_methods_gate()(solution.methods.*mode-gated leaves) behind one call so every consumer produces the same answer. When the path is not a recognized multi-path or mode-gated setting, returns a “pass-through”WriteTargetwithneeds_reroute=Falseandclassified=False— that is the signal to fall back to the default schema-only check.- Parameters:
- mode
Live solver mode facets (build via
SolverMode.from_state()).- path
Proposed write path (bracket-indexed forms accepted).
- Returns:
WriteTargetCanonical resolution. When
needs_rerouteis True,active_pathcarries the sibling to write instead (or, if a deterministic active path cannot be derived, equalsrequested_pathand the caller should surface thereasonverbatim rather than silently proceeding).
- active_path.describe_mode(mode: SolverMode) dict[str, Any]#
Return a compact JSON-safe summary of
mode.Suitable for embedding in a system prompt or a debug payload. Fields:
time—"steady"or"transient".solver_type—"pressure-based"or"density-based".flow_scheme— the raw p-v coupling string (may be None).coupled— bool.pseudo_transient— bool.urf_family— active URF family enum value.bc_namespace/cz_namespace/interface_namespace—"utl"or"standard".multiphase—Nonefor single-phase, else{model, phases}.turbulence_model/energy— passthrough.nita— bool.
- active_path.write_target_hints(mode: SolverMode) dict[str, Any]#
Return canonical write-target answers for the CURRENT
mode.Emits a small dict that any authoring surface (agent-loop system prompt, describe_path fallback, external host preflight) can turn into a short “when you write X, use path Y” guide. Contains ONLY facts derivable from
mode— no live tool calls, no schema probes.Keys:
urf_family— active URF family enum value.urf_root— the container path (segregated NamedObject root, coupled scalar prefix, or pseudo-time NamedObject root).urf_key_template— how to index into that root ("['for NamedObject families,']" ""for scalar leaves under the coupled-explicit family).run_calculation_path— active iterate command.bc_root/cz_root/interface_root— active namespace roots.multiphase—Nonefor single-phase, else a per-phase write-guidance dict:model— VOF / Mixture / Eulerian.phases— ordered list.mixture_level_bc_template—".. [' ']. " per_phase_bc_template—".. [' '].phase[' '].multiphase. " per_phase_bc_note— “which BC leaves are per-phase vs mixture-level varies by model — call describe_path to confirm”.
- active_path.format_mode_summary(mode: SolverMode) str#
Return a short human-readable summary of
modefor prompts.Two lines: one for the mode identity, one for the write-target hints (URF family, BC namespace, run command, multiphase state). Deliberately compact — the full JSON summary is available via
describe_mode()andwrite_target_hints()when a caller needs to inspect it.