TASK-032: Pressure Field (Stage 5) - #45
Merged
Merged
Conversation
Stage 5's third task. PISO (TASK-027, Stage 4) already performs the
solve this task's own criteria describe -- this adds no new
pressure-solving mechanism, only the properties Stage 4's own criteria
never had cause to check, plus the one genuinely missing API-level
guard:
- PressureField(ScalarField) (scalar_field.py): a thin marker subclass
resolving this task's own local design question ("pressure needs a
type of its own"). Lives here, not in pressure_coupling.py (its one
real producer), since simulation.py needs to import it and cannot
import from pressure_coupling.py without a circular import -- the
same reasoning that moved IncompatibleVelocityFieldError in TASK-031a.
- PISO.correct now constructs a PressureField instead of a plain
ScalarField. No interface change: PressureCoupling.correct's own
abstract signature stays tuple[VectorField, ScalarField], and a
PressureField instance already satisfies it.
- simulation.step gains a real isinstance check, raising the new
PressureFieldTransportError if fields contains a PressureField --
stated at the API level, since there's no configuration surface that
names which fields are transported.
Five new scenarios (tests/features/pressure_field.feature) prove: a
divergence-free provisional velocity yields pressure constant to
solver tolerance; a divergent one yields non-constant pressure; adding
a constant to the solved pressure leaves the corrected velocity
unchanged (the null-space remedy made observable); step rejects a
PressureField; and a boundary configuration violating the zero-net-flux
compatibility condition fails to load before any pressure solve is
attempted (Stage 3's existing check, not reimplemented).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stage 5's third task, built directly after TASK-031 in the roadmap's own build order.
PISO(TASK-027, Stage 4) already performs the solve this task's own criteria describe -- this task adds no new pressure-solving mechanism, only the properties Stage 4's own criteria never had cause to check, plus one genuinely missing API-level guard.The local design question resolved: pressure gets a type of its own.
PressureField(ScalarField)(scalar_field.py) is a thin marker subclass with no new behaviour. It lives inscalar_field.py, notengine/numerics/pressure_coupling.py(its one real producer) --simulation.pyneeds to import it and cannot import frompressure_coupling.pywithout a circular import (that module already importsaccumulate_flux_to_cellsfromsimulation.py). Same reasoning that movedIncompatibleVelocityFieldErrortovector_field.pyin TASK-031a.PISO.correctnow constructs aPressureFieldinstead of a plainScalarField. No interface change:PressureCoupling.correct's own abstract signature staystuple[VectorField, ScalarField], and aPressureFieldinstance already satisfies it (valid covariant return narrowing undermypy --strict).simulation.stepgains a realisinstancecheck, raising a newPressureFieldTransportErroriffieldscontains aPressureField-- stated at the API level deliberately, not the configuration level, since there's no configuration surface today that names which fields are transported (SimulationConfigseeds one scalar pattern and one velocity pattern, nothing more).Test plan
Five new scenarios (
tests/features/pressure_field.feature), checked against the realPISO/GreenGaussGradientmachinery directly:GreenGaussGradient).steprejects afieldsmapping containing aPressureFieldwith a named error, not silent transport._validate_boundary_conditions_jointly, not reimplemented).make cigreen: 647 tests passing, mypy--strictclean, 100% coverage on every changed module, all doc/graph/scenario/status/config-template checks pass.🤖 Generated with Claude Code