[PH-Flash] Add mixture enthalpy models with cited caloric data and baseline flash tests - #5297
[PH-Flash] Add mixture enthalpy models with cited caloric data and baseline flash tests#5297arturcastiel wants to merge 5 commits into
Conversation
Introduce a test-local two-component (methane/n-decane) Peng-Robinson fluid system and a data-driven case harness (FlashCase/runFlash) that applies the full PTFlash input contract, and pin the isothermal flash on it: single-phase labels, two-phase invariants (material balance, equal fugacity, K-consistency) and iteration-method parity (ssi, newton, ssi+newton). A ternary case reuses the in-tree ThreeComponentFluidSystem.
ComponentCp holds the species-blind caloric equations: a cubic ideal-gas heat-capacity polynomial and its closed-form enthalpy integral, zero at the reference datum. The coefficients live on the component classes (C1, C10, SimpleCO2) next to the species' other constants, each fitted to the ideal-gas part of the cited reference EoS over 250-600 K, with CoolProp-cross-checked triple points added alongside. A pin suite guards every card against tabulated reference-EoS values, so a corrupt coefficient row fails loudly instead of passing self-consistent tests.
…arture IdealGasCaloricData owns the shared enthalpy reference datum and the deck-style name lookup over the component caloric cards; unknown components fail loudly rather than receive somebody else's heat capacity. MixtureEnthalpy evaluates the molar enthalpy of a flashed compositional state behind a two-model seam: the caloric (ideal-gas) model, where the phase split cancels exactly by material balance, and the EoS-consistent departure model, where the residual enthalpy is obtained per phase from AD temperature-derivatives of the fluid system's own fugacity coefficients — no hand-derived EoS calculus. Tests cover monotonicity, the reference datum, analytic cp against a finite difference, split-cancellation, the AD derivative against a finite difference of ln(phi), the ideal-gas limit, split coupling of the departure model, and the shared model-name parser.
|
jenkins build this please |
|
jenkins build this please |
2 similar comments
|
jenkins build this please |
|
jenkins build this please |
|
@akva2 thank you. |
There was a problem hiding this comment.
Pull request overview
Adds compositional mixture-enthalpy evaluation as groundwork for P–H flash support.
Changes:
- Adds ideal-gas heat-capacity data and enthalpy integrals.
- Implements caloric and EoS-departure mixture enthalpy models.
- Adds binary flash fixtures and baseline tests.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
CMakeLists_files.cmake |
Registers headers and tests. |
opm/material/components/C1.hpp |
Adds methane caloric and triple-point data. |
opm/material/components/C10.hpp |
Adds decane caloric and triple-point data. |
opm/material/components/ComponentCp.hpp |
Defines heat-capacity polynomial integration. |
opm/material/components/SimpleCO2.hpp |
Adds CO₂ caloric data. |
opm/material/constraintsolvers/IdealGasCaloricData.hpp |
Provides caloric presets and name lookup. |
opm/material/constraintsolvers/MixtureEnthalpy.hpp |
Implements mixture enthalpy models. |
tests/material/flashTestFixtures.hpp |
Adds shared compositional flash fixtures. |
tests/material/test_mixture_enthalpy.cpp |
Tests caloric and departure behavior. |
tests/material/test_twocomponents_ptflash.cpp |
Adds P–T flash baseline tests. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| * there is deliberately NO silent fallback — an unknown component must | ||
| * fail loudly rather than receive somebody else's heat capacity. | ||
| */ | ||
| static ComponentCp<Scalar> byName(const std::string_view name) |
There was a problem hiding this comment.
Added ByNameAliasesAndUnknownName to test_mixture_enthalpy.cpp: every documented alias is pinned coefficient-wise against its card (mixed-case spellings included), and unknown/empty names are checked to throw. In 2e64598.
| FluidSystemF1::ParameterCache<double> paramCache(EOSType::PR); | ||
| paramCache.updatePhase(fs, phaseIdx); | ||
| return std::log(FluidSystemF1::fugacityCoefficient(fs, paramCache, phaseIdx, compIdx)); | ||
| }; | ||
|
|
||
| const double T = Opm::FlashTest::f1Temperature; | ||
| for (int compIdx = 0; compIdx < numComponentsF1; ++compIdx) { | ||
| const double ad = EnthalpyF1::phaseDLnPhiDT(outcome.state, phaseIdx, compIdx, EOSType::PR); |
There was a problem hiding this comment.
Done — the AD-vs-FD check now loops over PR, PRCORR, SRK and RK, passing the EoS type through both the scalar finite-difference path and phaseDLnPhiDT. The flashed composition is only a probe point (the AD == FD identity holds at any state), so the one state serves every EoS. In 2e64598.
| //! C1/nC10 Peng-Robinson binary interaction parameter — the value this | ||
| //! library's compositional tests use (cf. ThreeComponentFluidSystem). The | ||
| //! unequal-index shortcut in interactionCoefficient() is valid only | ||
| //! because the system is binary. |
There was a problem hiding this comment.
You're right — interactionCoefficient() there returns 0.0 for every pair and cannot establish this value. Reworded: 0.0411 is a pinned fixture value within the range of published C1/nC10 PR coefficients (roughly 0.04-0.05, source-dependent); the two-phase baselines built on it were cross-validated against an independent PR implementation (CoolProp) using this same value. Value unchanged. In 55a10ee.
…alpy tests Review follow-up on the mixture-enthalpy tests. byName() promises case-insensitive deck-style aliases and a loud throw on unknown components, but neither promise was exercised; and the AD-vs-finite- difference derivative check ran only under PR while the alpha-function temperature dependence branches per EoS type. Pin every documented alias coefficient-wise plus the unknown-name throw, and run the derivative identity over PR, PRCORR, SRK and RK — the flashed composition is only a probe point, so the one state serves every EoS.
The comment pointed at ThreeComponentFluidSystem::interactionCoefficient(), which returns zero for every pair and so cannot establish 0.0411. State the actual provenance instead: a pinned fixture value within the range of published C1/nC10 PR coefficients, cross-validated against an independent PR implementation with this same value. Value unchanged.
|
jenkins build this please |
|
@akva2 is there a reason why I cannot call jenkins? |
|
github is being troublesome and queues up my api calls and stalls for 30m-1h at times. it will likely trigger, it just takes time. |
The compositional path in opm-common cannot evaluate the enthalpy of a flashed mixture. This PR adds that capability — the groundwork for an isenthalpic (P–H) compositional flash, which follows in a separate PR.
What this adds
ComponentCp— cubic ideal-gas heat-capacity polynomial and its closed-form enthalpy integral. The coefficients live on the component classes (C1,C10,SimpleCO2) as cited identity cards, each fitted to the species' reference EoS (Setzmann & Wagner 1991; Lemmon & Span 2006; Span & Wagner 1996) over 250–600 K, with cross-checked triple points.IdealGasCaloricData— the shared enthalpy datum (H = 0 at 298.15 K) and a name-keyed lookup of the cards. Unknown components throw instead of silently receiving another species' data.MixtureEnthalpy— molar enthalpy of a flashed state under two models:caloric(ideal-gas; independent of the phase split by material balance) andeos_departure(adds the per-phase residualH_res = -R T² Σ w_i ∂lnφ_i/∂T). The temperature derivative is computed by automatic differentiation: temperature is seeded as a one-variableDenseAd::Evaluationand∂lnφ_i/∂Tis read from the fluid system's ownfugacityCoefficient— no hand-derived EoS calculus, so every EoS variant the fluid system supports is covered. The AD is internal to this evaluation; results are plain values.ssi/newton/ssi+newtonparity.Testing
About 65% of the diff is tests:
phaseDLnPhiDTexists for exactly this);Additive only — no existing behavior changes.