[AI-Assisted] fix(thermo): keep Mod2004 Born chemical potentials intensive - #3865
Merged
Merged
Conversation
Remove the unweighted dielectric derivative from dFBorndN, add electrolyte-family scaling and flash regressions, and document the chain rule, literature and remaining legacy limitations. Closes #3862
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.
Problem
ComponentModifiedFurstElectrolyteEosMod2004.dFBorndNadded the phase-level dielectric derivativeFBornD()directly to a mole derivative. Because that term is extensive, identical intensive states produced different chemical potentials, fugacity coefficients and flash results when only the amount basis changed.Closes #3862.
Changes
FBornD()term, preserving the 2004 model's existing zero solvent-permittivity derivative convention and its Born mixed derivatives.Dividing
FBornD()by total moles is not a valid substitute for the missing chain-rule factor.Other EOS audit
Base Furst, electrolyte CPA, Statoil, Advanced and MM already include the dielectric chain-rule factor. Their scaling regressions pass; MM is checked with MOLAR_AVERAGE, VOLUME_AVERAGE, LOOYENGA and LICHTENECKER. CPA Old inherits the base derivative (source inspection). Ordinary SRK/PR/CPA/non-electrolyte SAFT and Pitzer do not use the faulty Mod2004 implementation. This is a focused audit of this failure mode, not certification of every derivative in those models.
Literature and remaining scope
The documentation discusses Maribo-Mogensen et al. (2015, doi:10.1002/aic.14829), Simonin (2019, doi:10.1063/1.5096598), Novak et al. (2023, doi:10.1021/acs.iecr.3c00717), and Novak et al. (2025, doi:10.1016/j.fluid.2025.114339). Source claims were verified from publisher/institutional abstracts; the chain rule is independently derived from NeqSim's implemented energy.
The legacy 2004 model still recomputes permittivity with temperature/composition while suppressing those derivatives. This PR fixes phase-size dependence. Full mixed-solvent/caloric consistency requires coordinated Born and long-range derivative work and property validation; it is explicitly not claimed here. No fitted parameters or public signatures change.
Validation
Base:
a7f0e929559b27e70c841b763a77b6bf04c964ff; NeqSim 3.21.0 source; OpenJDK 17.0.20.Before the correction, the new amount-scaling and TP-flash assertions reproduce the failure. On the final implementation: 69 tests passed, zero failures/errors/skips, including all 11 new regressions.
Maven was bootstrapped with the work-with-neqsim
prepare_maven.pyhelper../mvnw -B -ntp -DskipTests -Dmaven.javadoc.skip=true -Djacoco.skip=true compile./mvnw -B -ntp -Dtest=ElectrolyteBornExtensivityTest -Djacoco.skip=true test./mvnw -B -ntp -Dtest='ElectrolyteBornExtensivityTest,SystemFurstElectrolyteEosTest,SystemElectrolyteCPATest,SystemElectrolyteCPAMMTest,SystemElectrolyteCPAAdvancedTest,PhaseModifiedFurstElectrolyteEosTest,PhaseModifiedFurstElectrolyteEosMod2004Test,PhaseElectrolyteCPATest,PhaseElectrolyteCPAstatoilTest,PhaseElectrolyteCPAOldTest' -Djacoco.skip=true testpython3 devtools/run_spotless.py apply(including clean repeat)python3 devtools/run_spotless.py checkpython3 devtools/check_documentation_search.pypre-commit run --all-files --hook-stage pre-commitpre-commit run --all-files --hook-stage pre-push./mvnw -B -ntp -DskipTests -DjavadocExecutable=<local-javadoc-launcher> javadoc:javadocgit diff --checkThe runtime includes the JDK javadoc module but no launcher, so the local launcher invokes that module and forwards JVM options. The first attempt without it was blocked by the missing executable. A task-local pre-commit installation was used because an existing launcher had missing dependencies. No environment workaround was added to the repository.
VALIDATION PENDING CI: GitHub's full Java/platform matrix was not run locally.
Documentation impact
Updated
docs/thermo/ElectrolyteCPAModel.md, addeddocs/thermo/ElectrolyteBornDerivatives.md, and documented the derivative convention in Javadoc. The new guide is linked from the existing electrolyte CPA documentation.Requested CI repair — latest validation
Remove the duplicate Born-guide heading caught by documentation tests. Preserve and freshly evaluate the lower endpoint in binary feasibility search so it remains available when interior candidates fail replay. Apply the compatible repair from #3801 and add a synthetic regression for the non-repeatable boundary. The regression was reproduced failing before the repair. Feasibility and utilization tolerances remain strict.
Current repair head:
47bd8d3125a14a4233d9814c8b68ab216d8861da, parent10adc61695abd5b42f7db4739a5d250b8d59b933. Earlier head and repair-budget notes above describe previous checkpoints; the user explicitly requested repair of all failing PRs.Local OpenJDK 17 validation: 6 focused tests passed, zero failures/errors/skips using
./mvnw -q -Dtest=ProductionOptimizerSelectedPointTest,BottleneckAnalysisOptimizerTest#testTwoStageOptimizationRecommendedApproach -DexcludedTestGroups= -Djacoco.skip=true test(exit 0).After Maven bootstrap with the NeqSim skill helper, the final tree passed all of the following (exit 0):
python3 devtools/run_spotless.py applytwice, with an unchanged repeated diff;python3 -m pre_commit run --all-files --hook-stage pre-commit;python3 devtools/run_spotless.py check;python3 devtools/check_documentation_search.py;python3 -m pre_commit run --all-files --hook-stage pre-push;git diff --checkandgit diff --cached --check;python3 -m unittest discover -s docs -p 'test_*.py'(386 passed).The selected primary Python runtime used task-local pre-commit dependencies. Documentation impact: document verified endpoint recovery before Debottlenecking Studies while preserving master's non-monotonic-envelope guidance. A three-way document merge against the actual shared base and exact master document exits 0. The previous documentation follow-up had a trailing blank line at EOF: its claim that every final gate passed was incorrect because the whitespace check exited 2. This commit removes that blank line; the complete gate sequence was rerun successfully before publication.
VALIDATION PENDING CI for the new head's hosted Java/platform checks. No merge or readiness change.