add initial constitutive relations api - #17
Conversation
| constexpr IonicStrength::Params testParams | ||
| { | ||
| // Species charge | ||
| { 1.0, -1.0, 2.0 } |
There was a problem hiding this comment.
The sum of charges needs to be 0. Suggesting to change 1.0 to -1.0
|
Bdot tests are expected to fail now. Need to update the expected solution. |
There was a problem hiding this comment.
I've heavily modified and refactored this file to account for the activity model during mass action solve. The root cause is secondary concentrations and activity coefficients are coupled (i.e., ionic strength depends on the secondary concentrations). So we should solve them together, and therefore, concentrations, activity coefficients and activities are mutually consistent.
The specific changes include:
-
Refactored
calculateLogSecondarySpeciesConcentrationandcalculateLogSecondarySpeciesConcentrationWrtLogC: an inner Newton solve onlog(C_sec)returning concentrations, activity coefficients, activities, a convergence flag, and the exactd log(C_sec)/d log(C_prim). -
Renamed the old fixed-activity-coefficient versions to
...NoActivityUpdateand...WrtLogCNoActivityUpdate. -
Removed the two
calculateAggregatePrimaryConcentrationsWrtLogCoverloads and thecalculateTotalAndMobileAggregatePrimaryConcentrationsWrtLogC, which reconstructed secondary concentrations internally undergamma == 1. The two remaining aggregate functions are a pure mole balance,T_i = C_prim,i + sum_j nu_ji C_sec,j, taking the solved secondary arrays as input.
There was a problem hiding this comment.
New tests added:
Self-consistent solve, checking mass action holds and a = C * gamma for all species:
test_calculateLogSecondarySpeciesConcentration_allEquilibrium_identitytest_calculateLogSecondarySpeciesConcentration_allEquilibrium_bdottest_calculateLogSecondarySpeciesConcentration_mixedSystem_identitytest_calculateLogSecondarySpeciesConcentration_mixedSystem_bdottest_calculateLogSecondarySpeciesConcentration_identityActivityModel— reproduces the reference
concentrations and confirms unit activity coefficients.
Derivative d log(C_sec)/d log(C_prim) against a central difference of the solve itself:
test_calculateLogSecondarySpeciesConcentrationWrtLogC_allEquilibrium_identitytest_calculateLogSecondarySpeciesConcentrationWrtLogC_allEquilibrium_bdottest_calculateLogSecondarySpeciesConcentrationWrtLogC_mixedSystem_bdot
…tro and refactored secondary species calculation
…computes the reaction rate to be textbook consistent
…pts for reference solutions of the bdot
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #17 +/- ##
===========================================
- Coverage 100.00% 99.08% -0.92%
===========================================
Files 25 34 +9
Lines 830 1309 +479
===========================================
+ Hits 830 1297 +467
- Misses 0 12 +12 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…, added a flag to run ideal solution as the initial guess to improve convergence
The primary goal of this PR is to enable a constitutive relation interface in
HPCReactfor computation of activity coefficients, ionic strength, and water activity.Specific changes include:
Adds a constitutive activity layer — a new
src/constitutive/module with a commoncalculateActivitiesAPI (activity/activity.hpp) and four models (Identity,DebyeHuckel,Drummond,Bdot).Drummondis for certain neutral species with a different activity coefficient calculation, e.g., CO2.Threads
ACTIVITY_MODELas a template parameter through the reaction stack —EquilibriumReactions,KineticReactions, andMixedEquilibriumKineticReactionsnow take activity parameters alongside reaction parameters, and every example system and unit test is templated on the model.Adds water as an explicit participant — activity models return
ln(a_w)with derivatives, and the parameter struct carries awaterStoichiometryarray so reactions with water (e.g.OH⁻ + H⁺ = H₂O,CO₂ + H₂O = H⁺ + HCO₃⁻) accounts for the water activity term.Refactors the secondary species calculation as a self-consistent inner Newton solve —
calculateLogSecondarySpeciesConcentrationnow iterates onlog C_secuntil concentrations, ionic strength, activity coefficients anda_ware mutually consistent at the given primary concentrations, andd log C_sec/d log C_primis recovered analytically from the converged constraint.Accounts for the activity model in both mass action and kinetic rate evaluation —
MassActionsconverts secondary activities back to concentrations for the mole balance of given aggregate/total concentration, while kinetic rates are evaluated on activities in both the elementary and affinity forms.Refactors the
reactionRatesUpdateOptioninteger with aReactionRateLawOptionenum (ElementaryvsAffinity) and renames the rate-evaluation entry point to textbook-consistent naming.Adds an ideal-solution presolve option (
HPCREACT_IDEAL_PRESOLVE) that solves theIdentityspeciation first (activity coefficient and water activity assumed to be unity) and uses it as the Newton initial guess for advanced models (e.g.,BDot), which is what makes the B-dot carbonate cases converge reliably.Adds EQ3/6 verification — the geochemistry carbonate system is populated with
data0.com.V8.R6logK values and phreeqc ion-size/b-dot parameters, with EQ3NR/EQ6 input-output decks checked in as reference, new tests for equilibrium, kinetic, and mixed carbonate cases, standalonetestBdot/testIonicStrengthunit tests, and Python scripts for the reference values of the simple example system.Note: This PR needs #21 and GEOS-DEV/GEOS#3996 as prerequisites as the activity model uses molality concentration by default as the input, while current GEOS
developconsiders molarity concentration.