From 3c79271cefbf8f40fdff49c6ce4fad354e9cf9cb Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 17 Jul 2025 14:44:52 -0500 Subject: [PATCH 01/28] Add Utilities class --- .../constitutive/CMakeLists.txt | 1 + .../functions/KValueInitialization.hpp | 10 +- .../functions/NegativeTwoPhaseFlash.hpp | 86 +------------ .../compositional/functions/StabilityTest.hpp | 75 +---------- .../compositional/functions/Utilities.hpp | 118 ++++++++++++++++++ .../models/NegativeTwoPhaseFlashModel.hpp | 27 ++++ .../testImmiscibleWaterFlashModel.cpp | 2 + .../unitTests/testNegativeTwoPhaseFlash.cpp | 22 +++- .../testNegativeTwoPhaseFlash9Comp.cpp | 21 +++- .../unitTests/testStabilityTest2Comp.cpp | 6 + .../unitTests/testStabilityTest9Comp.cpp | 12 ++ 11 files changed, 209 insertions(+), 171 deletions(-) create mode 100644 src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index 56df22e1f21..59b335a28f1 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -97,6 +97,7 @@ set( constitutive_headers fluid/multifluid/compositional/functions/SoreideWhitsonEOSPhaseModel_impl.hpp fluid/multifluid/compositional/functions/SoreideWhitsonEOSPhaseModel.hpp fluid/multifluid/compositional/functions/StabilityTest.hpp + fluid/multifluid/compositional/functions/Utilities.hpp fluid/multifluid/compositional/models/CompositionalDensity.hpp fluid/multifluid/compositional/models/ConstantViscosity.hpp fluid/multifluid/compositional/models/FunctionBase.hpp diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/KValueInitialization.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/KValueInitialization.hpp index 320262b7ab9..115221048c4 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/KValueInitialization.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/KValueInitialization.hpp @@ -21,6 +21,7 @@ #define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_KVALUEINITIALIZATION_HPP_ #include "common/DataTypes.hpp" +#include "constitutive/fluid/multifluid/MultiFluidConstants.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/ComponentProperties.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/ComponentType.hpp" @@ -71,7 +72,7 @@ struct KValueInitialization * @param[in] pressure pressure * @param[in] temperature temperature * @param[in] componentProperties The compositional component properties - * @param[in] presentComponents The list of present components (with non-zero mole fraction) + * @param[in] composition The composition of the fluid * @param[out] kValues the calculated k-values **/ template< integer USD > @@ -81,14 +82,14 @@ struct KValueInitialization real64 const pressure, real64 const temperature, ComponentProperties::KernelWrapper const & componentProperties, - arraySlice1d< integer const > const & presentComponents, + arraySlice1d< real64 const > const & composition, arraySlice1d< real64, USD > const & kValues ) { integer waterIndex = -1; auto const & componentType = componentProperties.m_componentType; - for( integer const ic : presentComponents ) + for( integer ic = 0; ic < numComps; ++ic ) { - if( isComponentType( componentType[ic], ComponentType::Water )) + if( MultiFluidConstants::epsilon < composition[ic] && isComponentType( componentType[ic], ComponentType::Water )) { waterIndex = ic; break; @@ -128,7 +129,6 @@ struct KValueInitialization { return exp( -4844.168051 / temperature + 12.93022442 ) * 1.0e5 / pressure; } - }; } // namespace compositional diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp index 040dea95547..8f0ca3abc6f 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp @@ -24,6 +24,7 @@ #include "KValueInitialization.hpp" #include "FugacityCalculator.hpp" #include "FlashData.hpp" +#include "Utilities.hpp" #include "constitutive/fluid/multifluid/MultiFluidConstants.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/ComponentProperties.hpp" #include "denseLinearAlgebra/interfaces/blaslapack/BlasLapackLA.hpp" @@ -99,59 +100,6 @@ struct NegativeTwoPhaseFlash arraySlice2d< real64, USD3 > const & vapourCompositionDerivs ); private: - /** - * @brief Calculate which components are present. - * @details Creates a list of indices whose components have non-zero mole fraction. - * @param[in] numComps number of components - * @param[in] composition the composition of the fluid - * @param[out] presentComponents the list of present components - * @return the number of present components - */ - template< typename ARRAY > - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - static integer calculatePresentComponents( integer const numComps, - arraySlice1d< real64 const > const & composition, - ARRAY & presentComponents ) - { - // Check for machine-zero feed values - integer presentCount = 0; - for( integer ic = 0; ic < numComps; ++ic ) - { - if( MultiFluidConstants::minForSpeciesPresence < composition[ic] ) - { - presentComponents[presentCount++] = ic; - } - } - presentComponents.resize( presentCount ); - return presentCount; - } - - /** - * @brief Normalise a composition in place to ensure that the components add up to unity - * @param[in] numComps number of components - * @param[in/out] composition composition to be normalized - * @return the sum of the given values - */ - template< integer USD > - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - static real64 normalizeComposition( integer const numComps, - arraySlice1d< real64, USD > const & composition ) - { - real64 totalMoles = 0.0; - for( integer ic = 0; ic < numComps; ++ic ) - { - totalMoles += composition[ic]; - } - real64 const oneOverTotalMoles = 1.0 / (totalMoles + MultiFluidConstants::epsilon); - for( integer ic = 0; ic < numComps; ++ic ) - { - composition[ic] *= oneOverTotalMoles; - } - return totalMoles; - } - /** * @brief Calculate the logarithms of the fugacity ratios * @param[in] numComps number of components @@ -242,38 +190,6 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, vapourComposition[ic] = composition[ic]; } - // Check if k-Values need to be initialised - bool needInitialisation = false; - for( integer ic = 0; ic < numComps; ++ic ) - { - if( kVapourLiquid[ic] < MultiFluidConstants::epsilon ) - { - needInitialisation = true; - break; - } - } - - if( needInitialisation ) - { - if( flashData.liquidEos == EquationOfStateType::SoreideWhitson ) - { - KValueInitialization::computeSoreideWhitsonKvalue( numComps, - pressure, - temperature, - componentProperties, - presentComponents, - kVapourLiquid ); - } - else - { - KValueInitialization::computeWilsonGasLiquidKvalue( numComps, - pressure, - temperature, - componentProperties, - kVapourLiquid ); - } - } - bool converged = false; for( localIndex iterationCount = 0; iterationCount < MultiFluidConstants::maxSSIIterations; ++iterationCount ) { diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp index 3074e34f498..9b82c322722 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp @@ -22,6 +22,7 @@ #include "KValueInitialization.hpp" #include "FugacityCalculator.hpp" +#include "Utilities.hpp" #include "constitutive/fluid/multifluid/Layouts.hpp" #include "constitutive/fluid/multifluid/MultiFluidConstants.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/ComponentProperties.hpp" @@ -93,26 +94,6 @@ struct StabilityTest hyperplane[ic] = LvArray::math::log( composition[ic] ) + logFugacity[ic]; } - if( equationOfState == EquationOfStateType::SoreideWhitson ) - { - // Initialise the trial compositions using SW uniform values - KValueInitialization::computeSoreideWhitsonKvalue( numComps, - pressure, - temperature, - componentProperties, - presentComponents, - kValues ); - } - else - { - // Initialise the trial compositions using Wilson k-Values - KValueInitialization::computeWilsonGasLiquidKvalue( numComps, - pressure, - temperature, - componentProperties, - kValues ); - } - // The mimimum TPD over all trial compositions tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; @@ -186,60 +167,6 @@ struct StabilityTest } return ( tangentPlaneDistance < -MultiFluidConstants::fugacityTolerance ) || (maxError < MultiFluidConstants::fugacityTolerance); } - -private: - /** - * @brief Calculate which components are present. - * @details Creates a list of indices whose components have non-zero mole fraction. - * @param[in] numComps number of components - * @param[in] composition the composition of the fluid - * @param[out] presentComponents the list of present components - * @return the number of present components - */ - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - static integer calculatePresentComponents( integer const numComps, - arraySlice1d< real64 const > const & composition, - stackArray1d< integer, maxNumComps > & presentComponents ) - { - // Check for machine-zero feed values - integer presentCount = 0; - for( integer ic = 0; ic < numComps; ++ic ) - { - if( MultiFluidConstants::epsilon < composition[ic] ) - { - presentComponents[presentCount++] = ic; - } - } - presentComponents.resize( presentCount ); - return presentCount; - } - - /** - * @brief Normalise a composition in place to ensure that the components add up to unity - * @param[in] numComps number of components - * @param[in/out] composition composition to be normalized - * @return the sum of the given values - */ - template< integer USD > - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - static real64 normalizeComposition( integer const numComps, - arraySlice1d< real64, USD > const & composition ) - { - real64 totalMoles = 0.0; - for( integer ic = 0; ic < numComps; ++ic ) - { - totalMoles += composition[ic]; - } - GEOS_ASSERT( MultiFluidConstants::epsilon < totalMoles ); - real64 const oneOverTotalMoles = 1.0 / totalMoles; - for( integer ic = 0; ic < numComps; ++ic ) - { - composition[ic] *= oneOverTotalMoles; - } - return totalMoles; - } }; } // namespace compositional diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp new file mode 100644 index 00000000000..224081b8e7f --- /dev/null +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp @@ -0,0 +1,118 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file Utilities.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_UTILITIES_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_UTILITIES_HPP_ + +#include "constitutive/fluid/multifluid/MultiFluidConstants.hpp" + +namespace geos +{ +namespace constitutive +{ +namespace compositional +{ + +/** + * @brief Set a value to zero. Used for array initialisation + */ +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +static void setZero( real64 & value ){ value = 0.0; } + +/** + * @brief Normalise a composition in place to ensure that the components add up to unity + * @param[in] numComps number of components + * @param[in/out] composition composition to be normalized + * @return the sum of the given values + */ +template< integer USD > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +static real64 normalizeComposition( integer const numComps, + arraySlice1d< real64, USD > const & composition ) +{ + real64 totalMoles = 0.0; + for( integer ic = 0; ic < numComps; ++ic ) + { + totalMoles += composition[ic]; + } + real64 const oneOverTotalMoles = 1.0 / (totalMoles + MultiFluidConstants::epsilon); + for( integer ic = 0; ic < numComps; ++ic ) + { + composition[ic] *= oneOverTotalMoles; + } + return totalMoles; +} + +/** + * @brief Checks if a composition array has numerically small values + * @param[in] numComps number of values in the composition array + * @param[in] composition composition to be checked + * @return true of there is one zero value + */ +template< integer USD > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +static bool hasZero( integer const numComps, + arraySlice1d< real64 const, USD > const & composition ) +{ + for( integer ic = 0; ic < numComps; ++ic ) + { + if( composition[ic] < MultiFluidConstants::epsilon ) + { + return true; + } + } + return false; +} + +/** + * @brief Calculate which components are present. + * @details Creates a list of indices whose components have non-zero mole fraction. + * @param[in] numComps number of components + * @param[in] composition the composition of the fluid + * @param[out] presentComponents the list of present components + * @return the number of present components + */ +template< integer USD, typename ARRAY > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +static integer calculatePresentComponents( integer const numComps, + arraySlice1d< real64 const, USD > const & composition, + ARRAY & presentComponents ) +{ + // Check for machine-zero feed values + integer presentCount = 0; + for( integer ic = 0; ic < numComps; ++ic ) + { + if( MultiFluidConstants::epsilon < composition[ic] ) + { + presentComponents[presentCount++] = ic; + } + } + presentComponents.resize( presentCount ); + return presentCount; +} + +} // namespace compositional +} // namespace constitutive +} // namespace geos + +#endif //GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_UTILITIES_HPP_ diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp index a12d7fc82c7..f0b9582394a 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp @@ -25,6 +25,7 @@ #include "constitutive/fluid/multifluid/Layouts.hpp" #include "constitutive/fluid/multifluid/MultiFluidUtils.hpp" +#include "constitutive/fluid/multifluid/compositional/functions/Utilities.hpp" #include "constitutive/fluid/multifluid/compositional/functions/FlashData.hpp" #include "constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp" #include "constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp" @@ -73,6 +74,32 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate { integer const numDofs = 2 + m_numComponents; + // Check if k-Values need to be initialised + auto kVapourLiquid = kValues[0]; + bool const needInitialisation = hasZero( m_numComponents, kVapourLiquid.toSliceConst() ); + if( needInitialisation ) + { + if( m_flashData.liquidEos == EquationOfStateType::SoreideWhitson ) + { + // Initialise the trial compositions using SW uniform values + KValueInitialization::computeSoreideWhitsonKvalue( m_numComponents, + pressure, + temperature, + componentProperties, + compFraction, + kVapourLiquid ); + } + else + { + // Initialise the trial compositions using Wilson k-Values + KValueInitialization::computeWilsonGasLiquidKvalue( m_numComponents, + pressure, + temperature, + componentProperties, + kVapourLiquid ); + } + } + // Perform stability test to check that we have 2 phases real64 tangentPlaneDistance = 0.0; bool const stabilityStatus = StabilityTest::compute( m_numComponents, diff --git a/src/coreComponents/constitutive/unitTests/testImmiscibleWaterFlashModel.cpp b/src/coreComponents/constitutive/unitTests/testImmiscibleWaterFlashModel.cpp index 3fd742a2673..6ecc3545c18 100644 --- a/src/coreComponents/constitutive/unitTests/testImmiscibleWaterFlashModel.cpp +++ b/src/coreComponents/constitutive/unitTests/testImmiscibleWaterFlashModel.cpp @@ -221,6 +221,8 @@ class ImmiscibleWaterFlashModelTestFixture : public ::testing::TestWithParam< F auto displacedPhaseComponentFraction = displacedPhaseComponentFractionData[0][0]; auto displacedPhaseComponentFractionDerivs = displacedPhaseComponentFractionDerivsData[0][0]; + LvArray::forValuesInSlice( kValues.toSlice(), []( real64 & v ){ v = 0.0; } ); + flashKernelWrapper.compute( componentProperties, p, t, diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash.cpp index 1aa3785d374..510439404d8 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash.cpp @@ -100,7 +100,12 @@ class NegativeTwoPhaseFlashTestFixture : public ::testing::TestWithParam< Flash auto const liquidComposition = compositionData[0]; auto const vapourComposition = compositionData[1]; stackArray2d< real64, numComps > kValues( 1, numComps ); - kValues.zero(); + + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + pressure, + temperature, + componentProperties, + kValues[0] ); bool status = NegativeTwoPhaseFlash::compute( numComps, @@ -164,7 +169,12 @@ class NegativeTwoPhaseFlashTestFixture : public ::testing::TestWithParam< Flash stackArray1d< real64, numComps > liquidComposition( numComps ); stackArray1d< real64, numComps > vapourComposition( numComps ); stackArray2d< real64, numComps > kValues( 1, numComps ); - kValues.zero(); + + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + pressure, + temperature, + componentProperties, + kValues[0] ); stackArray1d< real64, numDofs > vapourFractionDerivs( numDofs ); stackArray2d< real64, numComps * numDofs > liquidCompositionDerivs( numComps, numDofs ); @@ -180,12 +190,16 @@ class NegativeTwoPhaseFlashTestFixture : public ::testing::TestWithParam< Flash derivs[1+ic+numComps] = ymf( ic, kc ); } }; - std::cout << std::scientific << std::setprecision( 8 ); auto const evaluateFlash = [&]( real64 const p, real64 const t, auto const & zmf, auto & values ){ stackArray1d< real64, numComps > displacedLiquidComposition( numComps ); stackArray1d< real64, numComps > displacedVapourComposition( numComps ); - kValues.zero(); + + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + p, + t, + componentProperties, + kValues[0] ); NegativeTwoPhaseFlash::compute( numComps, diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp index a602cc5a028..89d4cd1b0df 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp @@ -81,7 +81,12 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< stackArray1d< real64, numComps > liquidComposition( numComps ); stackArray1d< real64, numComps > vapourComposition( numComps ); stackArray2d< real64, numComps > kValues( 1, numComps ); - kValues.zero(); + + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + pressure, + temperature, + componentProperties, + kValues[0] ); bool status = NegativeTwoPhaseFlash::compute( numComps, @@ -144,7 +149,12 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< stackArray1d< real64, numComps > liquidComposition( numComps ); stackArray1d< real64, numComps > vapourComposition( numComps ); stackArray2d< real64, numComps > kValues( 1, numComps ); - kValues.zero(); + + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + pressure, + temperature, + componentProperties, + kValues[0] ); stackArray1d< real64, numDofs > vapourFractionDerivs( numDofs ); stackArray2d< real64, numComps * numDofs > liquidCompositionDerivs( numComps, numDofs ); @@ -164,7 +174,12 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< auto const evaluateFlash = [&]( real64 const p, real64 const t, auto const & zmf, auto & values ){ stackArray1d< real64, numComps > displacedLiquidComposition( numComps ); stackArray1d< real64, numComps > displacedVapourComposition( numComps ); - kValues( 0, 0 ) = 0.0; + + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + p, + t, + componentProperties, + kValues[0] ); NegativeTwoPhaseFlash::compute( numComps, diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp index 8a402ad44eb..01639d0c46b 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp @@ -69,6 +69,12 @@ class StabilityTestTest2CompFixture : public ::testing::TestWithParam< Stabilit real64 tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; stackArray1d< real64, numComps > kValues( numComps ); + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + pressure, + temperature, + componentProperties, + kValues.toSlice() ); + bool const stabilityStatus = StabilityTest::compute( numComps, pressure, temperature, diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp index 229267000b9..6ac67ad4cc9 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp @@ -69,6 +69,12 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat real64 tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; stackArray1d< real64, numComps > kValues( numComps ); + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + pressure, + temperature, + componentProperties, + kValues.toSlice() ); + bool const stabilityStatus = StabilityTest::compute( numComps, pressure, temperature, @@ -102,6 +108,12 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat real64 tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; stackArray2d< real64, numComps > kValues( 1, numComps ); + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + pressure, + temperature, + componentProperties, + kValues[0] ); + StabilityTest::compute( numComps, pressure, temperature, From df7c29aa3983fae90f1edde8ffd3e8b3b6983a65 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 17 Jul 2025 15:39:01 -0500 Subject: [PATCH 02/28] Add stability flash parameters --- .../constitutive/CMakeLists.txt | 2 + .../compositional/functions/StabilityTest.hpp | 35 +- .../models/ImmiscibleWaterFlashModel.cpp | 14 +- .../models/ImmiscibleWaterFlashModel.hpp | 4 +- .../models/NegativeTwoPhaseFlashModel.cpp | 18 +- .../models/NegativeTwoPhaseFlashModel.hpp | 13 +- .../parameters/FlashParameters.cpp | 113 ++++++ .../parameters/FlashParameters.hpp | 84 ++++ .../constitutive/unitTests/CMakeLists.txt | 1 + .../testNegativeTwoPhaseFlashModel.cpp | 376 ++++++++++++++++++ .../unitTests/testStabilityTest2Comp.cpp | 5 + .../unitTests/testStabilityTest9Comp.cpp | 9 + 12 files changed, 651 insertions(+), 23 deletions(-) create mode 100644 src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp create mode 100644 src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp create mode 100644 src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index 59b335a28f1..53e2e95053b 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -116,6 +116,7 @@ set( constitutive_headers fluid/multifluid/compositional/parameters/ComponentType.hpp fluid/multifluid/compositional/parameters/CriticalVolume.hpp fluid/multifluid/compositional/parameters/EquationOfState.hpp + fluid/multifluid/compositional/parameters/FlashParameters.hpp fluid/multifluid/compositional/parameters/ImmiscibleWaterParameters.hpp fluid/multifluid/compositional/parameters/ModelParameters.hpp fluid/multifluid/compositional/parameters/PhaseType.hpp @@ -270,6 +271,7 @@ set( constitutive_sources fluid/multifluid/compositional/parameters/BrineSalinity.cpp fluid/multifluid/compositional/parameters/ComponentProperties.cpp fluid/multifluid/compositional/parameters/CriticalVolume.cpp + fluid/multifluid/compositional/parameters/FlashParameters.cpp fluid/multifluid/compositional/parameters/ImmiscibleWaterParameters.cpp fluid/multifluid/compositional/parameters/PhaseType.cpp fluid/multifluid/compositional/parameters/PressureTemperatureCoordinates.cpp diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp index 9b82c322722..d807c408112 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp @@ -26,6 +26,7 @@ #include "constitutive/fluid/multifluid/Layouts.hpp" #include "constitutive/fluid/multifluid/MultiFluidConstants.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/ComponentProperties.hpp" +#include "constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp" #include "constitutive/fluid/multifluid/compositional/functions/FlashData.hpp" namespace geos @@ -51,6 +52,8 @@ struct StabilityTest * @param[in] componentProperties The compositional component properties * @param[in] equationOfState The equation of state * @param[in] flashData The parameters required for the flash + * @param[in] continuousFlashParameters List of continuous (float) parameters for flash + * @param[in] discreteFlashParameters List of discrete (integer) parameters for flash * @param[out] tangentPlaneDistance the minimum tangent plane distance (TPD) * @param[out] kValues the k-values estimated from the stationary points * @return a flag indicating that 2 stationary points have been found @@ -64,6 +67,8 @@ struct StabilityTest ComponentProperties::KernelWrapper const & componentProperties, EquationOfStateType const & equationOfState, FlashData const & flashData, + arraySlice1d< real64 const > const & continuousFlashParameters, + arraySlice1d< integer const > const & discreteFlashParameters, real64 & tangentPlaneDistance, arraySlice1d< real64, USD2 > const & kValues ) { @@ -79,6 +84,11 @@ struct StabilityTest LvArray::forValuesInSlice( workSpace.toSlice(), []( real64 & a ){ a = 0.0; } ); + // Extract flash parameters + integer const maxIterations = discreteFlashParameters[FlashParameters::STABILITY_MAX_ITERATIONS]; + real64 const stabilityThreshold = continuousFlashParameters[FlashParameters::STABILITY_THRESHOLD]; + real64 const stabilityTolerance = continuousFlashParameters[FlashParameters::STABILITY_TOLERANCE]; + // Calculate the hyperplane parameter // h_i = log( z_i ) + log( phi_i ) FugacityCalculator::computeLogFugacity( numComps, @@ -97,10 +107,10 @@ struct StabilityTest // The mimimum TPD over all trial compositions tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; - // Maximum error (convergence failure) over all trial compositions - real64 maxError = -LvArray::NumericLimits< real64 >::max; + // Flag to indicate all trial compositions converged + bool allConverged = true; - for( real64 const & alpha : { 1.0, -1.0, 3.0, -3.0 } ) + for( real64 const alpha : { 1.0, -1.0, 3.0, -3.0 } ) { // Initialise next sample for( integer const ic : presentComponents ) @@ -109,8 +119,9 @@ struct StabilityTest normalizedComposition[ic] = LvArray::math::exp( logTrialComposition[ic] ); } - real64 trialError = LvArray::NumericLimits< real64 >::max; - for( localIndex iterationCount = 0; iterationCount < MultiFluidConstants::maxSSIIterations; ++iterationCount ) + // Start iterations for this sample + bool converged = false; + for( localIndex iterationCount = 0; iterationCount < maxIterations; ++iterationCount ) { // Normalise the composition and calculate the fugacity real64 const totalMoles = normalizeComposition( numComps, normalizedComposition ); @@ -133,8 +144,9 @@ struct StabilityTest { tangentPlaneDistance = tpd; } - if( tangentPlaneDistance < -MultiFluidConstants::fugacityTolerance ) + if( tangentPlaneDistance < stabilityThreshold ) { + converged = true; break; } @@ -146,9 +158,9 @@ struct StabilityTest error += (dG*dG); } error = LvArray::math::sqrt( error ); - trialError = LvArray::math::min( trialError, error ); - if( trialError < MultiFluidConstants::fugacityTolerance ) + if( error < stabilityTolerance ) { + converged = true; break; } @@ -159,13 +171,14 @@ struct StabilityTest normalizedComposition[ic] = LvArray::math::exp( logTrialComposition[ic] ); } } - maxError = LvArray::math::max( maxError, trialError ); - if( tangentPlaneDistance < -MultiFluidConstants::fugacityTolerance ) + allConverged = allConverged && converged; + if( tangentPlaneDistance < stabilityThreshold ) { break; } } - return ( tangentPlaneDistance < -MultiFluidConstants::fugacityTolerance ) || (maxError < MultiFluidConstants::fugacityTolerance); + // The test is successful if either we have a negative TPD or all test compositions converged to stationarity + return (tangentPlaneDistance < stabilityThreshold) || (allConverged); } }; diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/ImmiscibleWaterFlashModel.cpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/ImmiscibleWaterFlashModel.cpp index 684103197f2..cd6d7828dd3 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/ImmiscibleWaterFlashModel.cpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/ImmiscibleWaterFlashModel.cpp @@ -68,6 +68,8 @@ ImmiscibleWaterFlashModel::createKernelWrapper() const CriticalVolume const * criticalVolume = m_parameters.get< CriticalVolume >(); + FlashParameters const * flashParameters = m_parameters.get< FlashParameters >(); + return KernelWrapper( m_componentProperties.getNumberOfComponents(), liquidIndex, vapourIndex, @@ -76,7 +78,9 @@ ImmiscibleWaterFlashModel::createKernelWrapper() const liquidEos, vapourEos, salinity, - criticalVolume->m_componentCriticalVolume ); + criticalVolume->m_componentCriticalVolume, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters ); } ImmiscibleWaterFlashModelUpdate::ImmiscibleWaterFlashModelUpdate( @@ -88,14 +92,18 @@ ImmiscibleWaterFlashModelUpdate::ImmiscibleWaterFlashModelUpdate( EquationOfStateType const liquidEos, EquationOfStateType const vapourEos, real64 const salinity, - arrayView1d< real64 const > const componentCriticalVolume ): + arrayView1d< real64 const > const componentCriticalVolume, + arrayView1d< real64 const > const continuousFlashParameters, + arrayView1d< integer const > const discreteFlashParameters ): m_twoPhaseModel( numComponents, liquidIndex, vapourIndex, liquidEos, vapourEos, salinity, - componentCriticalVolume ), + componentCriticalVolume, + continuousFlashParameters, + discreteFlashParameters ), m_numComponents( numComponents ), m_liquidIndex( liquidIndex ), m_vapourIndex( vapourIndex ), diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/ImmiscibleWaterFlashModel.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/ImmiscibleWaterFlashModel.hpp index 2e835ef65aa..9176e4564e2 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/ImmiscibleWaterFlashModel.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/ImmiscibleWaterFlashModel.hpp @@ -56,7 +56,9 @@ class ImmiscibleWaterFlashModelUpdate final : public FunctionBaseUpdate EquationOfStateType const liquidEos, EquationOfStateType const vapourEos, real64 const salinity, - arrayView1d< real64 const > const componentCriticalVolume ); + arrayView1d< real64 const > const componentCriticalVolume, + arrayView1d< real64 const > const continuousFlashParameters, + arrayView1d< integer const > const discreteFlashParameters ); // Mark as a 3-phase flash GEOS_HOST_DEVICE diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.cpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.cpp index 08685018d85..a495a6a0ea5 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.cpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.cpp @@ -20,6 +20,7 @@ #include "NegativeTwoPhaseFlashModel.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/CriticalVolume.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/BrineSalinity.hpp" +#include "constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/PhaseType.hpp" namespace geos @@ -63,13 +64,17 @@ NegativeTwoPhaseFlashModel::createKernelWrapper() const CriticalVolume const * criticalVolume = m_parameters.get< CriticalVolume >(); + FlashParameters const * flashParameters = m_parameters.get< FlashParameters >(); + return KernelWrapper( m_componentProperties.getNumberOfComponents(), liquidIndex, vapourIndex, liquidEos, vapourEos, salinity, - criticalVolume->m_componentCriticalVolume ); + criticalVolume->m_componentCriticalVolume, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters ); } NegativeTwoPhaseFlashModelUpdate::NegativeTwoPhaseFlashModelUpdate( @@ -79,11 +84,15 @@ NegativeTwoPhaseFlashModelUpdate::NegativeTwoPhaseFlashModelUpdate( EquationOfStateType const liquidEos, EquationOfStateType const vapourEos, real64 const salinity, - arrayView1d< real64 const > const componentCriticalVolume ): + arrayView1d< real64 const > const componentCriticalVolume, + arrayView1d< real64 const > const continuousFlashParameters, + arrayView1d< integer const > const discreteFlashParameters ): m_numComponents( numComponents ), m_liquidIndex( liquidIndex ), m_vapourIndex( vapourIndex ), - m_componentCriticalVolume( componentCriticalVolume ) + m_componentCriticalVolume( componentCriticalVolume ), + m_continuousFlashParameters( continuousFlashParameters ), + m_discreteFlashParameters( discreteFlashParameters ) { m_flashData.liquidEos = liquidEos; m_flashData.vapourEos = vapourEos; @@ -93,7 +102,8 @@ NegativeTwoPhaseFlashModelUpdate::NegativeTwoPhaseFlashModelUpdate( std::unique_ptr< ModelParameters > NegativeTwoPhaseFlashModel::createParameters( std::unique_ptr< ModelParameters > parameters ) { - std::unique_ptr< ModelParameters > params = EquationOfState::create( std::move( parameters ) ); + std::unique_ptr< ModelParameters > params = FlashParameters::create( std::move( parameters ) ); + params = EquationOfState::create( std::move( params ) ); params = CriticalVolume::create( std::move( params ) ); return params; } diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp index f0b9582394a..dc9b6eb78c8 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp @@ -48,15 +48,15 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate using PhaseComp = MultiFluidVar< real64, 4, constitutive::multifluid::LAYOUT_PHASE_COMP, constitutive::multifluid::LAYOUT_PHASE_COMP_DC >; using Deriv = constitutive::multifluid::DerivativeOffset; - static constexpr real64 stabilityTolerance = MultiFluidConstants::fugacityTolerance; - NegativeTwoPhaseFlashModelUpdate( integer const numComponents, integer const liquidIndex, integer const vapourIndex, EquationOfStateType const liquidEos, EquationOfStateType const vapourEos, real64 const salinity, - arrayView1d< real64 const > const componentCriticalVolume ); + arrayView1d< real64 const > const componentCriticalVolume, + arrayView1d< real64 const > const continuousFlashParameters, + arrayView1d< integer const > const discreteFlashParameters ); // Mark as a 2-phase flash GEOS_HOST_DEVICE @@ -109,11 +109,14 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate componentProperties, m_flashData.liquidEos, m_flashData, + m_continuousFlashParameters.toSliceConst(), + m_discreteFlashParameters.toSliceConst(), tangentPlaneDistance, kValues[0] ); // If the stability test failed to converge to a stationary point then we will assume the mixture is unstable - if( tangentPlaneDistance < -stabilityTolerance || !stabilityStatus ) + real64 const stabilityThreshold = m_continuousFlashParameters[FlashParameters::STABILITY_THRESHOLD]; + if( tangentPlaneDistance < stabilityThreshold || !stabilityStatus ) { // Unstable mixture // Iterative solve to converge flash @@ -207,6 +210,8 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate integer const m_vapourIndex; FlashData m_flashData; arrayView1d< real64 const > const m_componentCriticalVolume; + arrayView1d< real64 const > const m_continuousFlashParameters; + arrayView1d< integer const > const m_discreteFlashParameters; }; class NegativeTwoPhaseFlashModel : public FunctionBase diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp new file mode 100644 index 00000000000..b8a236256f2 --- /dev/null +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp @@ -0,0 +1,113 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file FlashParameters.cpp + */ + +#include "FlashParameters.hpp" +#include "ComponentProperties.hpp" + +#include "constitutive/fluid/multifluid/MultiFluidBase.hpp" + +namespace geos +{ + +namespace constitutive +{ + +namespace compositional +{ + +FlashParameters::FlashParameters( std::unique_ptr< ModelParameters > parameters ): + ModelParameters( std::move( parameters ) ), + m_continuousParameters( NUM_FLOAT ), + m_discreteParameters( NUM_INTEGER ) +{ + m_continuousParameters[STABILITY_THRESHOLD] = -1.0e-8; + m_continuousParameters[STABILITY_TOLERANCE] = 1.0e-8; + + m_discreteParameters[STABILITY_MAX_ITERATIONS] = 300; +} + +std::unique_ptr< ModelParameters > FlashParameters::create( std::unique_ptr< ModelParameters > parameters ) +{ + if( parameters && parameters->get< FlashParameters >() != nullptr ) + { + return parameters; + } + return std::make_unique< FlashParameters >( std::move( parameters ) ); +} + +void FlashParameters::registerParametersImpl( MultiFluidBase * fluid ) +{ + fluid->registerWrapper( viewKeyStruct::stabilityThresholdString(), &m_continuousParameters[STABILITY_THRESHOLD] ). + setInputFlag( dataRepository::InputFlags::OPTIONAL ). + setDefaultValue( m_continuousParameters[STABILITY_THRESHOLD] ). + setDescription( "The value of the tangent plane distance below which a mixture is determined to be unstable" ); + + fluid->registerWrapper( viewKeyStruct::stabilityToleranceString(), &m_continuousParameters[STABILITY_TOLERANCE] ). + setInputFlag( dataRepository::InputFlags::OPTIONAL ). + setDefaultValue( m_continuousParameters[STABILITY_TOLERANCE] ). + setDescription( "The tolerance to use to determine convergence to a stationary point in the stability test" ); + + fluid->registerWrapper( viewKeyStruct::stabilityMaxIterationsString(), &m_discreteParameters[STABILITY_MAX_ITERATIONS] ). + setInputFlag( dataRepository::InputFlags::OPTIONAL ). + setDefaultValue( m_discreteParameters[STABILITY_MAX_ITERATIONS] ). + setDescription( "The maximum number of successive substitution iterations used during the stability test" ); +} + +void FlashParameters::postInputInitializationImpl( MultiFluidBase const * fluid, + ComponentProperties const & componentProperties ) +{ + GEOS_UNUSED_VAR( componentProperties ); + + auto const checkLowerBound = [&]( auto const & value, auto const & bound, string const & attribute ) + { + GEOS_THROW_IF_LT_MSG( value, bound, + GEOS_FMT( "{}: invalid number of value in attribute '{}'. Should be greater than {}", + fluid->getFullName(), bound, attribute ), + InputError ); + }; + + auto const checkUpperBound = [&]( auto const & value, auto const & bound, string const & attribute ) + { + GEOS_THROW_IF_GT_MSG( value, bound, + GEOS_FMT( "{}: invalid number of value in attribute '{}'. Should be less than {}", + fluid->getFullName(), bound, attribute ), + InputError ); + }; + + real64 constexpr epsilon = MultiFluidConstants::epsilon; + + // Stability threshold should be negative in the range [-10^{-2}, -10^{-14}] + real64 const stabilityThreshold = m_continuousParameters[STABILITY_THRESHOLD]; + checkUpperBound( stabilityThreshold, -1.0e-14, viewKeyStruct::stabilityThresholdString() ); + checkLowerBound( stabilityThreshold, -1.0e-2, viewKeyStruct::stabilityThresholdString() ); + + // Stability tolerance should be positive + real64 const stabilityTolerance = m_continuousParameters[STABILITY_TOLERANCE]; + checkLowerBound( stabilityTolerance, epsilon, viewKeyStruct::stabilityThresholdString() ); + + // Max number of iterations should be at least 1 + integer const stabilityMaxIterations = m_discreteParameters[STABILITY_MAX_ITERATIONS]; + checkLowerBound( stabilityMaxIterations, 1, viewKeyStruct::stabilityMaxIterationsString() ); +} + +} // end namespace compositional + +} // end namespace constitutive + +} // end namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp new file mode 100644 index 00000000000..6f121ea5adb --- /dev/null +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp @@ -0,0 +1,84 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file FlashParameters.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_PARAMETERS_FLASHPARAMETERS_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_PARAMETERS_FLASHPARAMETERS_HPP_ + +#include "ModelParameters.hpp" +#include "common/DataTypes.hpp" + +namespace geos +{ + +namespace constitutive +{ + +namespace compositional +{ + +class FlashParameters : public ModelParameters +{ +public: + /** + * Flash variables + * These are indices into an array that holds the actual values + */ + /** The value of the tangent plane distance below which a mixture is determined to be unstable. */ + static integer constexpr STABILITY_THRESHOLD = 0; + + /** The maximum number of iterations used during the stability test. */ + static integer constexpr STABILITY_MAX_ITERATIONS = 0; + + /** The tolerance to use to determine convergece to a stationary point in the stability test. */ + static integer constexpr STABILITY_TOLERANCE = 1; + + /* Number of continuous variables */ + static integer constexpr NUM_FLOAT = 2; + /* Number of discrete variables */ + static integer constexpr NUM_INTEGER = 1; + +public: + FlashParameters( std::unique_ptr< ModelParameters > parameters ); + ~FlashParameters() override = default; + + static std::unique_ptr< ModelParameters > create( std::unique_ptr< ModelParameters > parameters ); + + struct viewKeyStruct + { + static constexpr char const * stabilityThresholdString() { return "stabilityThreshold"; } + static constexpr char const * stabilityToleranceString() { return "stabilityTolerance"; } + static constexpr char const * stabilityMaxIterationsString() { return "stabilityMaxIterations"; } + }; + + array1d< real64 > m_continuousParameters; + array1d< integer > m_discreteParameters; + +protected: + void registerParametersImpl( MultiFluidBase * fluid ) override; + + void postInputInitializationImpl( MultiFluidBase const * fluid, ComponentProperties const & componentProperties ) override; +}; + +} // end namespace compositional + +} // end namespace constitutive + +} // end namespace geos + +#endif //GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_PARAMETERS_FLASHPARAMETERS_HPP_ diff --git a/src/coreComponents/constitutive/unitTests/CMakeLists.txt b/src/coreComponents/constitutive/unitTests/CMakeLists.txt index 426d4bb34fb..a00d86a63aa 100644 --- a/src/coreComponents/constitutive/unitTests/CMakeLists.txt +++ b/src/coreComponents/constitutive/unitTests/CMakeLists.txt @@ -24,6 +24,7 @@ set( gtest_geosx_tests testMultiFluidSelector.cpp testNegativeTwoPhaseFlash.cpp testNegativeTwoPhaseFlash9Comp.cpp + testNegativeTwoPhaseFlashModel.cpp testParticleFluidEnums.cpp testPressureTemperatureCoordinates.cpp testPropertyConversions.cpp diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp new file mode 100644 index 00000000000..4289f6a6015 --- /dev/null +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp @@ -0,0 +1,376 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +// Source includes +#include "codingUtilities/UnitTestUtilities.hpp" +#include "constitutive/fluid/multifluid/MultiFluidUtils.hpp" +#include "constitutive/fluid/multifluid/compositional/parameters/EquationOfState.hpp" +#include "constitutive/fluid/multifluid/compositional/parameters/CriticalVolume.hpp" +#include "constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp" +#include "constitutive/fluid/multifluid/compositional/parameters/PhaseType.hpp" +#include "TestFluid.hpp" +#include "TestFluidUtilities.hpp" + +using namespace geos::constitutive; +using namespace geos::constitutive::compositional; + +namespace geos +{ +namespace testing +{ + +constexpr integer numTestComps = 3; + +template< integer NC > +using FlashData = std::tuple< + real64 const, // pressure + real64 const, // temperature + Feed< NC > const, // phase composition + real64 const, // expected liquid fraction + real64 const, // expected vapour fraction + Feed< numTestComps > const, // expected liquid mole fractions + Feed< numTestComps > const // expected vapour mole fractions + >; + +template< integer NC > +struct FluidData {}; + +template<> +struct FluidData< 3 > +{ + static constexpr integer testComponents[numTestComps] = {0, 1, 2}; + static std::unique_ptr< TestFluid< 3 > > createFluid() + { + auto fluid = TestFluid< 3 >::create( {Fluid::CH4, Fluid::C10H22, Fluid::H2O} ); + const std::array< real64 const, 3 > bics = { 0.25, 0.0, 0.0 }; + fluid->setBinaryCoefficients( bics ); + return fluid; + } +}; + +template<> +struct FluidData< 9 > +{ + static constexpr integer testComponents[numTestComps] = {0, 3, 8}; + static std::unique_ptr< TestFluid< 9 > > createFluid() + { + auto fluid = TestFluid< 9 >::create( {Fluid::H2O, Fluid::CO2, Fluid::N2, Fluid::CH4, Fluid::C2H6, Fluid::C3H8, Fluid::C4H10, Fluid::C5H12, Fluid::C8H18} ); + const std::array< real64 const, 36 > bics = { + 0.01, 0, 0.003732, 0, 0.01, 0, 0, 0.01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0.01, 0, 0.028, 0.01, 0.01, 0, 0, 0.01, 0, 0.04532, 0.01, 0.01, 0, 0, 0 + }; + fluid->setBinaryCoefficients( bics ); + return fluid; + } +}; + +template< integer NC > +class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< FlashData< NC > > +{ + static constexpr real64 relTol = 1.0e-5; + static constexpr real64 absTol = 1.0e-7; + static constexpr integer numPhases = 2; + static constexpr integer numComps = NC; + static constexpr integer numDofs = NC + 2; + using Deriv = geos::constitutive::multifluid::DerivativeOffset; + using PhasePropSlice = NegativeTwoPhaseFlashModelUpdate::PhaseProp::SliceType; + using PhaseCompSlice = NegativeTwoPhaseFlashModelUpdate::PhaseComp::SliceType; + +public: + NegativeTwoPhaseFlashModelTestFixture() + : m_fluid( FluidData< NC >::createFluid() ) + { + ComponentProperties const & componentProperties = this->m_fluid->getComponentProperties(); + + m_parameters = NegativeTwoPhaseFlashModel::createParameters( std::move( m_parameters ) ); + + auto * equationOfState = const_cast< EquationOfState * >(m_parameters->get< EquationOfState >()); + string const eosName = EnumStrings< EquationOfStateType >::toString( EquationOfStateType::PengRobinson ); + equationOfState->m_equationsOfStateNames.emplace_back( eosName ); + equationOfState->m_equationsOfStateNames.emplace_back( eosName ); + + auto * criticalVolume = const_cast< CriticalVolume * >(m_parameters->get< CriticalVolume >()); + criticalVolume->m_componentCriticalVolume.resize( numComps ); + TestFluid< NC >::createArray( criticalVolume->m_componentCriticalVolume, this->m_fluid->criticalVolume ); + +m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); + m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::VAPOUR)); + + m_flash = std::make_unique< NegativeTwoPhaseFlashModel >( "FlashModel", componentProperties, *m_parameters, m_phaseTypes ); + } + + ~NegativeTwoPhaseFlashModelTestFixture() = default; + + void testFlash( FlashData< NC > const & data ) + { + real64 const pressure = std::get< 0 >( data ); + real64 const temperature = std::get< 1 >( data ); + stackArray1d< real64, numComps > composition; + TestFluid< NC >::createArray( composition, std::get< 2 >( data )); + + real64 const expectedPhaseFraction[numPhases] = {std::get< 3 >( data ), std::get< 4 >( data ) }; + Feed< numTestComps > const expectedPhaseComponentFraction[numPhases] = {std::get< 5 >( data ), std::get< 6 >( data ) }; + + stackArray2d< real64, (numPhases-1)*numComps > kValues( numPhases-1, numComps ); + LvArray::forValuesInSlice( kValues.toSlice(), []( real64 & v ){ v = 0.0; } ); + + StackArray< real64, 3, numPhases, multifluid::LAYOUT_PHASE > phaseFractionData( 1, 1, numPhases ); + StackArray< real64, 4, numPhases *numDofs, multifluid::LAYOUT_PHASE_DC > dPhaseFractionData( 1, 1, numPhases, numDofs ); + StackArray< real64, 4, numPhases *numComps, multifluid::LAYOUT_PHASE_COMP > phaseComponentFractionData( 1, 1, numPhases, numComps ); + StackArray< real64, 5, numPhases *numComps *numDofs, multifluid::LAYOUT_PHASE_COMP_DC > dPhaseComponentFractionData( 1, 1, numPhases, numComps, numDofs ); + + auto phaseFraction = phaseFractionData[0][0]; + auto dPhaseFraction = dPhaseFractionData[0][0]; + auto phaseComponentFraction = phaseComponentFractionData[0][0]; + auto dPhaseComponentFraction = dPhaseComponentFractionData[0][0]; + + auto componentProperties = m_fluid->createKernelWrapper(); + auto flashKernelWrapper = m_flash->createKernelWrapper(); + + flashKernelWrapper.compute( componentProperties, + pressure, + temperature, + composition.toSliceConst(), + kValues.toSlice(), + PhasePropSlice( phaseFraction, dPhaseFraction ), + PhaseCompSlice( phaseComponentFraction, dPhaseComponentFraction ) ); + + for( integer ip = 0; ip < numPhases; ip++ ) + { + checkRelativeError( phaseFraction[ip], expectedPhaseFraction[ip], relTol, absTol ); + for( integer i = 0; i < numTestComps; ++i ) + { + integer const ic = FluidData< numComps >::testComponents[i]; + checkRelativeError( phaseComponentFraction[ip][ic], expectedPhaseComponentFraction[ip][i], relTol, absTol ); + } + } + } + + void testFlashDerivatives( FlashData< NC > const & data ) + { + std::cout << std::fixed << std::setprecision( 8 ); + // Number of output values from each flash calculation + constexpr integer numValues = numPhases * (1 + numComps); + + real64 const pressure = std::get< 0 >( data ); + real64 const temperature = std::get< 1 >( data ); + stackArray1d< real64, numComps > composition; + TestFluid< NC >::createArray( composition, std::get< 2 >( data )); + + stackArray2d< real64, (numPhases-1)*numComps > kValues( numPhases-1, numComps ); + LvArray::forValuesInSlice( kValues.toSlice(), []( real64 & v ){ v = 0.0; } ); + + StackArray< real64, 3, numPhases, multifluid::LAYOUT_PHASE > phaseFractionData( 1, 1, numPhases ); + StackArray< real64, 4, numPhases *numDofs, multifluid::LAYOUT_PHASE_DC > dPhaseFractionData( 1, 1, numPhases, numDofs ); + StackArray< real64, 4, numPhases *numComps, multifluid::LAYOUT_PHASE_COMP > phaseComponentFractionData( 1, 1, numPhases, numComps ); + StackArray< real64, 5, numPhases *numComps *numDofs, multifluid::LAYOUT_PHASE_COMP_DC > dPhaseComponentFractionData( 1, 1, numPhases, numComps, numDofs ); + + auto phaseFraction = phaseFractionData[0][0]; + auto dPhaseFraction = dPhaseFractionData[0][0]; + auto phaseComponentFraction = phaseComponentFractionData[0][0]; + auto dPhaseComponentFraction = dPhaseComponentFractionData[0][0]; + + stackArray1d< real64, numValues > derivatives( numValues ); + + auto componentProperties = m_fluid->createKernelWrapper(); + auto flashKernelWrapper = m_flash->createKernelWrapper(); + flashKernelWrapper.compute( componentProperties, + pressure, + temperature, + composition.toSliceConst(), + kValues.toSlice(), + PhasePropSlice( phaseFraction, dPhaseFraction ), + PhaseCompSlice( phaseComponentFraction, dPhaseComponentFraction ) ); + + +/** + + Z: { 0.10900000, 0.00300000, 0.23470000, 0.11460000, 0.08790000, 0.04560000, 0.02090000, 0.01510000, 0.36920000 } + X: { 0.15807941, 0.00337666, 0.07159711, 0.02384273, 0.10085780, 0.06146075, 0.02939718, 0.00974393, 0.54164443 } + Y: { 0.00396181, 0.00219389, 0.58376764, 0.30883583, 0.06016813, 0.01165533, 0.00271459, 0.02656289, 0.00013988 } + + */ + std::cout << " Z: " << composition.toSliceConst() << std::endl; + std::cout << " X: " << phaseComponentFraction[0] << std::endl; + std::cout << " Y: " << phaseComponentFraction[1] << std::endl; + std::cout << " V: " << phaseFraction.toSliceConst() << std::endl; + std::cout << std::scientific; + std::cout << "DV: " << dPhaseFraction[0] << std::endl; + std::cout << "DV: " << dPhaseFraction[1] << std::endl; +/** + // Combine derivatives into a single output + auto const concatDerivatives = []( integer const kc, auto & derivs, auto const & phaseFractionDerivs, auto const & + phaseComponentFractionDerivs ){ + integer j = 0; + for( integer ip = 0; ip < numPhases; ++ip ) + { + derivs[j++] = phaseFractionDerivs( ip, kc ); + for( integer ic = 0; ic < numComps; ++ic ) + { + derivs[j++] = phaseComponentFractionDerivs( ip, ic, kc ); + } + } + }; + + auto const evaluateFlash = [&]( real64 const p, real64 const t, auto const & zmf, auto & values ){ + StackArray< real64, 3, numPhases, multifluid::LAYOUT_PHASE > displacedPhaseFractionData( 1, 1, numPhases ); + StackArray< real64, 4, numPhases *numDofs, multifluid::LAYOUT_PHASE_DC > displacedPhaseFractionDerivsData( 1, 1, numPhases, numDofs ); + StackArray< real64, 4, numPhases *numComps, multifluid::LAYOUT_PHASE_COMP > displacedPhaseComponentFractionData( 1, 1, numPhases, + numComps ); + StackArray< real64, 5, numPhases *numComps *numDofs, multifluid::LAYOUT_PHASE_COMP_DC > displacedPhaseComponentFractionDerivsData( 1, + 1, numPhases, numComps, numDofs ); + + auto displacedPhaseFraction = displacedPhaseFractionData[0][0]; + auto displacedPhaseFractionDerivs = displacedPhaseFractionDerivsData[0][0]; + auto displacedPhaseComponentFraction = displacedPhaseComponentFractionData[0][0]; + auto displacedPhaseComponentFractionDerivs = displacedPhaseComponentFractionDerivsData[0][0]; + + flashKernelWrapper.compute( componentProperties, + p, + t, + zmf, + kValues.toSlice(), + PhasePropSlice( displacedPhaseFraction, displacedPhaseFractionDerivs ), + PhaseCompSlice( displacedPhaseComponentFraction, displacedPhaseComponentFractionDerivs ) ); + integer j = 0; + for( integer ip = 0; ip < numPhases; ++ip ) + { + values[j++] = displacedPhaseFraction[ip]; + for( integer ic = 0; ic < numComps; ++ic ) + { + values[j++] = displacedPhaseComponentFraction( ip, ic ); + } + } + }; + + // Test against numerically calculated values + // --- Pressure derivatives --- + concatDerivatives( Deriv::dP, derivatives, dPhaseFraction, dPhaseComponentFraction ); + real64 const dp = 1.0e-4 * pressure; + geos::testing::internal::testNumericalDerivative< numValues >( + pressure, dp, derivatives, + [&]( real64 const p, auto & values ) { + evaluateFlash( p, temperature, composition.toSliceConst(), values ); + } ); + + // -- Temperature derivative + concatDerivatives( Deriv::dT, derivatives, dPhaseFraction, dPhaseComponentFraction ); + real64 const dT = 1.0e-6 * temperature; + geos::testing::internal::testNumericalDerivative< numValues >( + temperature, dT, derivatives, + [&]( real64 const t, auto & values ) { + evaluateFlash( pressure, t, composition.toSliceConst(), values ); + } ); + + // -- Composition derivatives derivative + real64 const dz = 1.0e-7; + for( integer const ic : FluidData< numComps >::testComponents ) + { + real64 sumZ = 0.0; + for( integer jc = 0; jc < numComps; ++jc ) + { + sumZ += composition[jc]; + } + sumZ -= composition[ic]; + if( sumZ < absTol ) + { + continue; + } + concatDerivatives( Deriv::dC+ic, derivatives, dPhaseFraction, dPhaseComponentFraction ); + geos::testing::internal::testNumericalDerivative< numValues >( + 0.0, dz, derivatives, + [&]( real64 const z, auto & values ) { + stackArray1d< real64, numComps > zmf( numComps ); + for( integer jc = 0; jc < numComps; ++jc ) + { + zmf[jc] = composition[jc]; + } + zmf[ic] += z; + evaluateFlash( pressure, temperature, zmf.toSliceConst(), values ); + } ); + } + */ + } + +protected: + std::unique_ptr< TestFluid< NC > > m_fluid{}; + std::unique_ptr< NegativeTwoPhaseFlashModel > m_flash{}; + std::unique_ptr< ModelParameters > m_parameters{}; + array1d< integer > m_phaseTypes{}; +}; + +//using NegativeTwoPhaseFlashModel3 = NegativeTwoPhaseFlashModelTestFixture< 3 >; +using NegativeTwoPhaseFlashModel9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; + +//TEST_P( NegativeTwoPhaseFlashModel3, testFlash ) +//{ +// testFlash( GetParam() ); +//} +//TEST_P( NegativeTwoPhaseFlashModel3, testFlashDerivatives ) +//{ +// testFlashDerivatives( GetParam() ); +//} + +//TEST_P( NegativeTwoPhaseFlashModel9, testFlash ) +//{ +// testFlash( GetParam() ); +//} +TEST_P( NegativeTwoPhaseFlashModel9, testFlashDerivatives ) +{ + testFlashDerivatives( GetParam() ); +} + +//------------------------------------------------------------------------------- +// Data +//------------------------------------------------------------------------------- +/* UNCRUSTIFY-OFF */ + +INSTANTIATE_TEST_SUITE_P( + NegativeTwoPhaseFlashModel, NegativeTwoPhaseFlashModel9, + ::testing::ValuesIn>({ + {1.0000e+07, 293.15, {0.10900000, 0.00300000, 0.23470000, 0.11460000, 0.08790000, 0.04560000, 0.02090000, 0.01510000, 0.36920000}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}}, + {1.5000e+07, 293.15, {0.13701652, 0.00320982, 0.10906376, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883838}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}}, + {1.0000e+07, 293.15, {0.13701652, 0.00320982, 0.10906376, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883838}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}}, + {0.9999e+07, 293.15, {0.13701652, 0.00320982, 0.10906376, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883838}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} + //FlashData<9>{1.0000e+07, 293.15, {0.00396181, 0.00219389, 0.58376764, 0.30883583, 0.06016813, 0.01165533, 0.00271459, 0.02656289, 0.00013988}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} + + /**, + FlashData<9>{1.0e+06, 293.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.198828, 0.792172, 0.009000, {0.000000, 0.011551, 0.850986}, {0.000000, 0.672081, 0.000000}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+07, 293.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.307007, 0.683993, 0.009000, {0.000000, 0.111647, 0.551128}, {0.000000, 0.731621, 0.000000}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+08, 293.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.991000, 0.000000, 0.009000, {0.000000, 0.539556, 0.170737}, {0.000000, 0.539556, 0.170737}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+06, 313.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.190493, 0.800507, 0.009000, {0.000000, 0.010985, 0.888223}, {0.000000, 0.665337, 0.000000}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+07, 313.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.288620, 0.702380, 0.009000, {0.000000, 0.106713, 0.586237}, {0.000000, 0.717418, 0.000001}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+08, 313.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.991000, 0.000000, 0.009000, {0.000000, 0.539556, 0.170737}, {0.000000, 0.539556, 0.170737}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+06, 353.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.181787, 0.809213, 0.009000, {0.000000, 0.010453, 0.930750}, {0.000000, 0.658417, 0.000003}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+07, 353.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.261660, 0.729340, 0.009000, {0.000000, 0.101277, 0.646622}, {0.000000, 0.696794, 0.000007}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+08, 353.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.947424, 0.043576, 0.009000, {0.000000, 0.529993, 0.178339}, {0.000000, 0.747468, 0.005438}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+06, 293.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.120388, 0.479612, 0.400000, {0.000000, 0.011551, 0.850996}, {0.000000, 0.672084, 0.000000}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+08, 293.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.600000, 0.000000, 0.400000, {0.000000, 0.539550, 0.170750}, {0.000000, 0.539550, 0.170750}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+06, 313.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.115342, 0.484658, 0.400000, {0.000000, 0.010985, 0.888229}, {0.000000, 0.665341, 0.000000}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+07, 313.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.174755, 0.425245, 0.400000, {0.000000, 0.106714, 0.586247}, {0.000000, 0.717425, 0.000001}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+08, 313.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.600000, 0.000000, 0.400000, {0.000000, 0.539550, 0.170750}, {0.000000, 0.539550, 0.170750}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+06, 353.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.110071, 0.489929, 0.400000, {0.000000, 0.010453, 0.930753}, {0.000000, 0.658421, 0.000003}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+07, 353.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.158432, 0.441568, 0.400000, {0.000000, 0.101278, 0.646630}, {0.000000, 0.696800, 0.000007}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+08, 353.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.573644, 0.026356, 0.400000, {0.000000, 0.529997, 0.178345}, {0.000000, 0.747479, 0.005437}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+06, 313.15, {1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000}, 0.000000, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}, {1.000000, 0.000000, 0.000000}}, + FlashData<9>{1.0e+08, 353.15, {1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000}, 0.000000, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}, {1.000000, 0.000000, 0.000000}}*/ + }) +); + +/* UNCRUSTIFY-ON */ + +} // testing + +} // geos diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp index 01639d0c46b..45b5864ef4a 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp @@ -75,6 +75,9 @@ class StabilityTestTest2CompFixture : public ::testing::TestWithParam< Stabilit componentProperties, kValues.toSlice() ); + auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); + auto const * flashParameters = parameters->get< FlashParameters >(); + bool const stabilityStatus = StabilityTest::compute( numComps, pressure, temperature, @@ -82,6 +85,8 @@ class StabilityTestTest2CompFixture : public ::testing::TestWithParam< Stabilit componentProperties, EOS_TYPE, flashData, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, tangentPlaneDistance, kValues.toSlice() ); diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp index 6ac67ad4cc9..d9d8f645362 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp @@ -75,6 +75,9 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat componentProperties, kValues.toSlice() ); + auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); + auto const * flashParameters = parameters->get< FlashParameters >(); + bool const stabilityStatus = StabilityTest::compute( numComps, pressure, temperature, @@ -82,6 +85,8 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat componentProperties, EOS_TYPE, flashData, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, tangentPlaneDistance, kValues.toSlice() ); @@ -113,6 +118,8 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat temperature, componentProperties, kValues[0] ); + auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); + auto const * flashParameters = parameters->get< FlashParameters >(); StabilityTest::compute( numComps, pressure, @@ -121,6 +128,8 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat componentProperties, EOS_TYPE, flashData, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, tangentPlaneDistance, kValues[0] ); From 39e24878bd9cb637a6ece23de47b754460d1b88c Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 17 Jul 2025 15:40:37 -0500 Subject: [PATCH 03/28] Copy file Step 1 --- .../{NegativeTwoPhaseFlash.hpp => NegativeTwoPhaseFlash_impl.hpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/coreComponents/constitutive/fluid/multifluid/compositional/functions/{NegativeTwoPhaseFlash.hpp => NegativeTwoPhaseFlash_impl.hpp} (100%) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp similarity index 100% rename from src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp rename to src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp From d593e70a98eca79229f90841e6df89799bedfd97 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 17 Jul 2025 15:41:17 -0500 Subject: [PATCH 04/28] Copy file Step 2 --- .../{NegativeTwoPhaseFlash.hpp => NegativeTwoPhaseFlash_copy.hpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/coreComponents/constitutive/fluid/multifluid/compositional/functions/{NegativeTwoPhaseFlash.hpp => NegativeTwoPhaseFlash_copy.hpp} (100%) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_copy.hpp similarity index 100% rename from src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp rename to src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_copy.hpp From d887daf20330533bd9a140f11c6d5c708ded0995 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 17 Jul 2025 17:31:43 -0500 Subject: [PATCH 05/28] Split negative flash into 2 files --- .../constitutive/CMakeLists.txt | 1 + .../functions/NegativeTwoPhaseFlash.hpp | 156 ++++++ .../functions/NegativeTwoPhaseFlash_copy.hpp | 461 ------------------ .../functions/NegativeTwoPhaseFlash_impl.hpp | 148 +----- 4 files changed, 176 insertions(+), 590 deletions(-) create mode 100644 src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_copy.hpp diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index 53e2e95053b..dae28e482e0 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -92,6 +92,7 @@ set( constitutive_headers fluid/multifluid/compositional/functions/FlashData.hpp fluid/multifluid/compositional/functions/FugacityCalculator.hpp fluid/multifluid/compositional/functions/KValueInitialization.hpp + fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp fluid/multifluid/compositional/functions/RachfordRice.hpp fluid/multifluid/compositional/functions/SoreideWhitsonEOSPhaseModel_impl.hpp diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp new file mode 100644 index 00000000000..ab620ea8345 --- /dev/null +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp @@ -0,0 +1,156 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file NegativeTwoPhaseFlash.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_HPP_ + +#include "FlashData.hpp" +#include "constitutive/fluid/multifluid/Layouts.hpp" +#include "constitutive/fluid/multifluid/compositional/parameters/ComponentProperties.hpp" + +namespace geos +{ + +namespace constitutive +{ +namespace compositional +{ + +struct NegativeTwoPhaseFlash +{ + using Deriv = constitutive::multifluid::DerivativeOffset; + +public: + /** + * @brief Perform negative two-phase EOS flash + * @param[in] numComps number of components + * @param[in] pressure pressure + * @param[in] temperature temperature + * @param[in] composition composition of the mixture + * @param[in] componentProperties The compositional component properties + * @param[in] flashData The parameters required for the flash + * @param[in/out] kValues The phase equilibrium ratios + * @param[out] vapourPhaseMoleFraction the calculated vapour (gas) mole fraction + * @param[out] liquidComposition the calculated liquid phase composition + * @param[out] vapourComposition the calculated vapour phase composition + * @return an indicator of success of the flash + */ + template< int USD1, int USD2 > + GEOS_HOST_DEVICE + static bool compute( integer const numComps, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + arraySlice2d< real64, USD1 > const & kValues, + real64 & vapourPhaseMoleFraction, + arraySlice1d< real64, USD2 > const & liquidComposition, + arraySlice1d< real64, USD2 > const & vapourComposition ); + + /** + * @brief Calculate derivatives from the two-phase negative flash + * @param[in] numComps number of components + * @param[in] pressure pressure + * @param[in] temperature temperature + * @param[in] composition composition of the mixture + * @param[in] componentProperties The compositional component properties + * @param[in] flashData The parameters required for the flash + * @param[in] vapourFraction the calculated vapour (gas) mole fraction + * @param[in] liquidComposition the calculated liquid phase composition + * @param[in] vapourComposition the calculated vapour phase composition + * @param[out] vapourFractionDerivs derivatives of the calculated vapour (gas) mole fraction + * @param[out] liquidCompositionDerivs derivatives of the calculated liquid phase composition + * @param[out] vapourCompositionDerivs derivatives of the calculated vapour phase composition + */ + template< integer USD1, integer USD2, integer USD3 > + GEOS_HOST_DEVICE + static void computeDerivatives( integer const numComps, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + real64 const & vapourFraction, + arraySlice1d< real64 const, USD1 > const & liquidComposition, + arraySlice1d< real64 const, USD1 > const & vapourComposition, + arraySlice1d< real64, USD2 > const & vapourFractionDerivs, + arraySlice2d< real64, USD3 > const & liquidCompositionDerivs, + arraySlice2d< real64, USD3 > const & vapourCompositionDerivs ); + +private: + /** + * @brief Calculate the logarithms of the fugacity ratios + * @param[in] numComps number of components + * @param[in] pressure pressure + * @param[in] temperature temperature + * @param[in] composition composition of the mixture + * @param[in] componentProperties The compositional component properties + * @param[in] flashData The parameters required for the flash + * @param[in] kValues The k-values + * @param[in] presentComponents The indices of the present components + * @param[out] vapourPhaseMoleFraction the calculated vapour (gas) mole fraction + * @param[out] liquidComposition the calculated liquid phase composition + * @param[out] vapourComposition the calculated vapour phase composition + * @param[out] logLiquidFugacity the calculated log fugacity ratios for the liquid phase + * @param[out] logVapourFugacity the calculated log fugacity ratios for the vapour phase + * @param[out] fugacityRatios the fugacity rations + * @return The error + */ + template< integer USD1, integer USD2 > + GEOS_HOST_DEVICE + static real64 computeFugacityRatio( + integer const numComps, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + arraySlice1d< real64 const, USD1 > const & kValues, + arraySlice1d< integer const > const & presentComponents, + real64 & vapourPhaseMoleFraction, + arraySlice1d< real64, USD2 > const & liquidComposition, + arraySlice1d< real64, USD2 > const & vapourComposition, + arraySlice1d< real64 > const & logLiquidFugacity, + arraySlice1d< real64 > const & logVapourFugacity, + arraySlice1d< real64 > const & fugacityRatios ); + + /** + * @brief Solve the lineat system for the derivatives of the flash + * @param[in/out] A the coefficient matrix. Destroyed after call + * @param[in/out] X the rhs and solution + * @return @c true if the problem is well solved @c false otherwise + */ + template< int USD > + GEOS_HOST_DEVICE + static bool solveLinearSystem( arraySlice2d< real64, USD > const & A, + arraySlice2d< real64, USD > const & X ); + +}; + +} // namespace compositional + +} // namespace constitutive + +} // namespace geos + +// Include the implementation +#include "NegativeTwoPhaseFlash_impl.hpp" + +#endif //GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_HPP_ diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_copy.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_copy.hpp deleted file mode 100644 index 8f0ca3abc6f..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_copy.hpp +++ /dev/null @@ -1,461 +0,0 @@ -/* - * ------------------------------------------------------------------------------------------------------------ - * SPDX-License-Identifier: LGPL-2.1-only - * - * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC - * Copyright (c) 2018-2024 TotalEnergies - * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University - * Copyright (c) 2023-2024 Chevron - * Copyright (c) 2019- GEOS/GEOSX Contributors - * All rights reserved - * - * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. - * ------------------------------------------------------------------------------------------------------------ - */ - -/** - * @file NegativeTwoPhaseFlash.hpp - */ - -#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_HPP_ -#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_HPP_ - -#include "RachfordRice.hpp" -#include "KValueInitialization.hpp" -#include "FugacityCalculator.hpp" -#include "FlashData.hpp" -#include "Utilities.hpp" -#include "constitutive/fluid/multifluid/MultiFluidConstants.hpp" -#include "constitutive/fluid/multifluid/compositional/parameters/ComponentProperties.hpp" -#include "denseLinearAlgebra/interfaces/blaslapack/BlasLapackLA.hpp" - -namespace geos -{ - -namespace constitutive -{ -namespace compositional -{ - -struct NegativeTwoPhaseFlash -{ - using Deriv = constitutive::multifluid::DerivativeOffset; - -public: - /** - * @brief Perform negative two-phase EOS flash - * @param[in] numComps number of components - * @param[in] pressure pressure - * @param[in] temperature temperature - * @param[in] composition composition of the mixture - * @param[in] componentProperties The compositional component properties - * @param[in] flashData The parameters required for the flash - * @param[in/out] kValues The phase equilibrium ratios - * @param[out] vapourPhaseMoleFraction the calculated vapour (gas) mole fraction - * @param[out] liquidComposition the calculated liquid phase composition - * @param[out] vapourComposition the calculated vapour phase composition - * @return an indicator of success of the flash - */ - template< int USD1, int USD2 > - GEOS_HOST_DEVICE - static bool compute( integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - arraySlice2d< real64, USD1 > const & kValues, - real64 & vapourPhaseMoleFraction, - arraySlice1d< real64, USD2 > const & liquidComposition, - arraySlice1d< real64, USD2 > const & vapourComposition ); - - /** - * @brief Calculate derivatives from the two-phase negative flash - * @param[in] numComps number of components - * @param[in] pressure pressure - * @param[in] temperature temperature - * @param[in] composition composition of the mixture - * @param[in] componentProperties The compositional component properties - * @param[in] flashData The parameters required for the flash - * @param[in] vapourFraction the calculated vapour (gas) mole fraction - * @param[in] liquidComposition the calculated liquid phase composition - * @param[in] vapourComposition the calculated vapour phase composition - * @param[out] vapourFractionDerivs derivatives of the calculated vapour (gas) mole fraction - * @param[out] liquidCompositionDerivs derivatives of the calculated liquid phase composition - * @param[out] vapourCompositionDerivs derivatives of the calculated vapour phase composition - */ - template< integer USD1, integer USD2, integer USD3 > - GEOS_HOST_DEVICE - static void computeDerivatives( integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - real64 const & vapourFraction, - arraySlice1d< real64 const, USD1 > const & liquidComposition, - arraySlice1d< real64 const, USD1 > const & vapourComposition, - arraySlice1d< real64, USD2 > const & vapourFractionDerivs, - arraySlice2d< real64, USD3 > const & liquidCompositionDerivs, - arraySlice2d< real64, USD3 > const & vapourCompositionDerivs ); - -private: - /** - * @brief Calculate the logarithms of the fugacity ratios - * @param[in] numComps number of components - * @param[in] pressure pressure - * @param[in] temperature temperature - * @param[in] composition composition of the mixture - * @param[in] componentProperties The compositional component properties - * @param[in] flashData The parameters required for the flash - * @param[in] kValues The k-values - * @param[in] presentComponents The indices of the present components - * @param[out] vapourPhaseMoleFraction the calculated vapour (gas) mole fraction - * @param[out] liquidComposition the calculated liquid phase composition - * @param[out] vapourComposition the calculated vapour phase composition - * @param[out] logLiquidFugacity the calculated log fugacity ratios for the liquid phase - * @param[out] logVapourFugacity the calculated log fugacity ratios for the vapour phase - * @param[out] fugacityRatios the fugacity rations - * @return The error - */ - template< integer USD1, integer USD2 > - GEOS_HOST_DEVICE - static real64 computeFugacityRatio( - integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - arraySlice1d< real64 const, USD1 > const & kValues, - arraySlice1d< integer const > const & presentComponents, - real64 & vapourPhaseMoleFraction, - arraySlice1d< real64, USD2 > const & liquidComposition, - arraySlice1d< real64, USD2 > const & vapourComposition, - arraySlice1d< real64 > const & logLiquidFugacity, - arraySlice1d< real64 > const & logVapourFugacity, - arraySlice1d< real64 > const & fugacityRatios ); - - /** - * @brief Solve the lineat system for the derivatives of the flash - * @param[in/out] A the coefficient matrix. Destroyed after call - * @param[in/out] X the rhs and solution - * @return @c true if the problem is well solved @c false otherwise - */ - template< int USD > - GEOS_HOST_DEVICE - static bool solveLinearSystem( arraySlice2d< real64, USD > const & A, - arraySlice2d< real64, USD > const & X ) - { -#if defined(GEOS_DEVICE_COMPILE) - GEOS_UNUSED_VAR( A ); - GEOS_UNUSED_VAR( X ); - return false; -#else - BlasLapackLA::solveLinearSystem( A, X ); - return true; -#endif - } - -}; - -template< int USD1, int USD2 > -GEOS_HOST_DEVICE -bool NegativeTwoPhaseFlash::compute( integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - arraySlice2d< real64, USD1 > const & kValues, - real64 & vapourPhaseMoleFraction, - arraySlice1d< real64, USD2 > const & liquidComposition, - arraySlice1d< real64, USD2 > const & vapourComposition ) -{ - constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; - stackArray1d< real64, maxNumComps > logLiquidFugacity( numComps ); - stackArray1d< real64, maxNumComps > logVapourFugacity( numComps ); - stackArray1d< real64, maxNumComps > fugacityRatios( numComps ); - stackArray1d< integer, maxNumComps > componentIndices( numComps ); - auto const & kVapourLiquid = kValues[0]; - - calculatePresentComponents( numComps, composition, componentIndices ); - - auto const presentComponents = componentIndices.toSliceConst(); - - // Initialise compositions to feed composition - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidComposition[ic] = composition[ic]; - vapourComposition[ic] = composition[ic]; - } - - bool converged = false; - for( localIndex iterationCount = 0; iterationCount < MultiFluidConstants::maxSSIIterations; ++iterationCount ) - { - real64 const error = computeFugacityRatio( numComps, - pressure, - temperature, - composition, - componentProperties, - flashData, - kVapourLiquid.toSliceConst(), - presentComponents, - vapourPhaseMoleFraction, - liquidComposition, - vapourComposition, - logLiquidFugacity.toSlice(), - logVapourFugacity.toSlice(), - fugacityRatios.toSlice() ); - - // Compute fugacity ratios and check convergence - converged = (error < MultiFluidConstants::fugacityTolerance); - - if( converged ) - { - break; - } - - // Update K-values - for( integer ic = 0; ic < numComps; ++ic ) - { - kVapourLiquid[ic] *= exp( fugacityRatios[ic] ); - } - } - - // Retrieve physical bounds from negative flash values - if( vapourPhaseMoleFraction < MultiFluidConstants::epsilon ) - { - vapourPhaseMoleFraction = 0.0; - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidComposition[ic] = composition[ic]; - vapourComposition[ic] = composition[ic]; - } - } - else if( 1.0 - vapourPhaseMoleFraction < MultiFluidConstants::epsilon ) - { - vapourPhaseMoleFraction = 1.0; - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidComposition[ic] = composition[ic]; - vapourComposition[ic] = composition[ic]; - } - } - - return converged; -} - -template< integer USD1, integer USD2, integer USD3 > -GEOS_HOST_DEVICE -void NegativeTwoPhaseFlash::computeDerivatives( - integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - real64 const & vapourFraction, - arraySlice1d< real64 const, USD1 > const & liquidComposition, - arraySlice1d< real64 const, USD1 > const & vapourComposition, - arraySlice1d< real64, USD2 > const & vapourFractionDerivs, - arraySlice2d< real64, USD3 > const & liquidCompositionDerivs, - arraySlice2d< real64, USD3 > const & vapourCompositionDerivs ) -{ - constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; - constexpr integer maxNumDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; - - integer const numDofs = numComps + 2; - - auto const setZero = []( real64 & val ) { val = 0.0; }; - LvArray::forValuesInSlice( vapourFractionDerivs, setZero ); - LvArray::forValuesInSlice( liquidCompositionDerivs, setZero ); - LvArray::forValuesInSlice( vapourCompositionDerivs, setZero ); - - // Check if we are single or 2-phase - if( vapourFraction < MultiFluidConstants::epsilon ) - { - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidCompositionDerivs( ic, Deriv::dC + ic ) = 1.0; - vapourCompositionDerivs( ic, Deriv::dC + ic ) = 1.0; - } - } - else if( 1.0 - vapourFraction < MultiFluidConstants::epsilon ) - { - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidCompositionDerivs( ic, Deriv::dC + ic ) = 1.0; - vapourCompositionDerivs( ic, Deriv::dC + ic ) = 1.0; - } - } - else - { - // Calculate the liquid and vapour fugacities and derivatives - StackArray< real64, 1, maxNumComps > logLiquidFugacity( numComps ); - StackArray< real64, 1, maxNumComps > logVapourFugacity( numComps ); - StackArray< real64, 2, maxNumComps * maxNumDofs, MatrixLayout::ROW_MAJOR_PERM > logLiquidFugacityDerivs( numComps, numDofs ); - StackArray< real64, 2, maxNumComps * maxNumDofs, MatrixLayout::ROW_MAJOR_PERM > logVapourFugacityDerivs( numComps, numDofs ); - - FugacityCalculator::computeLogFugacityDerivatives( numComps, - pressure, - temperature, - liquidComposition, - componentProperties, - flashData.liquidEos, - flashData, - logLiquidFugacity.toSlice(), - logLiquidFugacityDerivs.toSlice() ); - FugacityCalculator::computeLogFugacityDerivatives( numComps, - pressure, - temperature, - vapourComposition, - componentProperties, - flashData.vapourEos, - flashData, - logVapourFugacity.toSlice(), - logVapourFugacityDerivs.toSlice() ); - - constexpr integer maxNumVals = 2*MultiFluidConstants::MAX_NUM_COMPONENTS+1; - integer const numVals = 2*numComps; - StackArray< real64, 2, maxNumVals * maxNumVals, MatrixLayout::COL_MAJOR_PERM > A( numVals + 1, numVals + 1 ); - StackArray< real64, 2, maxNumVals * maxNumVals, MatrixLayout::COL_MAJOR_PERM > X( numVals + 1, numVals + 1 ); - - LvArray::forValuesInSlice( A.toSlice(), setZero ); - LvArray::forValuesInSlice( X.toSlice(), setZero ); - - for( integer ic = 0; ic < numComps; ++ic ) - { - integer const xi = ic; - integer const yi = ic + numComps; - integer const vi = numVals; - - integer e = ic; - A( e, xi ) = 1.0 - vapourFraction; - A( e, yi ) = vapourFraction; - A( e, vi ) = vapourComposition[ic] - liquidComposition[ic]; - - e = ic + numComps; - real64 const phiL = exp( logLiquidFugacity( ic ) ); - real64 const phiV = exp( logVapourFugacity( ic ) ); - for( integer jc = 0; jc < numComps; ++jc ) - { - integer const xj = jc; - integer const yj = jc + numComps; - real64 const dPhiLdx = logLiquidFugacityDerivs( ic, Deriv::dC+jc ); - real64 const dPhiVdy = logVapourFugacityDerivs( ic, Deriv::dC+jc ); - A( e, xj ) = liquidComposition[ic] * phiL * dPhiLdx; - A( e, yj ) = -vapourComposition[ic] * phiV * dPhiVdy; - } - A( e, xi ) += phiL; - A( e, yi ) -= phiV; - - e = numVals; - A( e, xi ) = -1.0; - A( e, yi ) = 1.0; - } - - // Pressure and temperature derivatives - for( integer ic = 0; ic < numComps; ++ic ) - { - real64 const phiL = -liquidComposition[ic] * exp( logLiquidFugacity( ic ) ); - real64 const phiV = vapourComposition[ic] * exp( logVapourFugacity( ic ) ); - X( ic + numComps, Deriv::dP ) = phiL * logLiquidFugacityDerivs( ic, Deriv::dP ) + - phiV * logVapourFugacityDerivs( ic, Deriv::dP ); - X( ic + numComps, Deriv::dT ) = phiL * logLiquidFugacityDerivs( ic, Deriv::dT ) + - phiV * logVapourFugacityDerivs( ic, Deriv::dT ); - } - - // Composition derivatives - for( integer kc = 0; kc < numComps; ++kc ) - { - integer const idof = Deriv::dC + kc; - - for( integer ic = 0; ic < numComps; ++ic ) - { - X( ic, idof ) = -composition[ic]; - } - X( kc, idof ) += 1.0; - } - - // Solve linear system - solveLinearSystem( A.toSlice(), X.toSlice() ); - - // Fill in the derivatives - for( integer idof = 0; idof < numDofs; ++idof ) - { - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidCompositionDerivs( ic, idof ) = X( ic, idof ); - vapourCompositionDerivs( ic, idof ) = X( ic + numComps, idof ); - } - vapourFractionDerivs( idof ) = X( numVals, idof ); - } - } -} - -template< integer USD1, integer USD2 > -GEOS_HOST_DEVICE -real64 NegativeTwoPhaseFlash::computeFugacityRatio( - integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - arraySlice1d< real64 const, USD1 > const & kValues, - arraySlice1d< integer const > const & presentComponents, - real64 & vapourPhaseMoleFraction, - arraySlice1d< real64, USD2 > const & liquidComposition, - arraySlice1d< real64, USD2 > const & vapourComposition, - arraySlice1d< real64 > const & logLiquidFugacity, - arraySlice1d< real64 > const & logVapourFugacity, - arraySlice1d< real64 > const & fugacityRatios ) -{ - // Solve Rachford-Rice Equation - vapourPhaseMoleFraction = RachfordRice::solve( kValues, composition, presentComponents ); - - // Assign phase compositions - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidComposition[ic] = composition[ic] / ( 1.0 + vapourPhaseMoleFraction * ( kValues[ic] - 1.0 ) ); - vapourComposition[ic] = kValues[ic] * liquidComposition[ic]; - } - - normalizeComposition( numComps, liquidComposition ); - normalizeComposition( numComps, vapourComposition ); - - FugacityCalculator::computeLogFugacity( numComps, - pressure, - temperature, - liquidComposition.toSliceConst(), - componentProperties, - flashData.liquidEos, - flashData, - logLiquidFugacity ); - FugacityCalculator::computeLogFugacity( numComps, - pressure, - temperature, - vapourComposition.toSliceConst(), - componentProperties, - flashData.vapourEos, - flashData, - logVapourFugacity ); - - // Compute fugacity ratios and calculate the error - real64 error = 0.0; - for( integer const ic : presentComponents ) - { - fugacityRatios[ic] = ( logLiquidFugacity[ic] - logVapourFugacity[ic] ) + log( liquidComposition[ic] ) - log( vapourComposition[ic] ); - error += (fugacityRatios[ic]*fugacityRatios[ic]); - } - return LvArray::math::sqrt( error ); -} - -} // namespace compositional - -} // namespace constitutive - -} // namespace geos - -#endif //GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_HPP_ diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index 8f0ca3abc6f..549328daf56 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -14,19 +14,16 @@ */ /** - * @file NegativeTwoPhaseFlash.hpp + * @file NegativeTwoPhaseFlash_impl.hpp */ -#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_HPP_ -#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_HPP_ +#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_IMPL_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_IMPL_HPP_ #include "RachfordRice.hpp" #include "KValueInitialization.hpp" #include "FugacityCalculator.hpp" -#include "FlashData.hpp" #include "Utilities.hpp" -#include "constitutive/fluid/multifluid/MultiFluidConstants.hpp" -#include "constitutive/fluid/multifluid/compositional/parameters/ComponentProperties.hpp" #include "denseLinearAlgebra/interfaces/blaslapack/BlasLapackLA.hpp" namespace geos @@ -37,128 +34,6 @@ namespace constitutive namespace compositional { -struct NegativeTwoPhaseFlash -{ - using Deriv = constitutive::multifluid::DerivativeOffset; - -public: - /** - * @brief Perform negative two-phase EOS flash - * @param[in] numComps number of components - * @param[in] pressure pressure - * @param[in] temperature temperature - * @param[in] composition composition of the mixture - * @param[in] componentProperties The compositional component properties - * @param[in] flashData The parameters required for the flash - * @param[in/out] kValues The phase equilibrium ratios - * @param[out] vapourPhaseMoleFraction the calculated vapour (gas) mole fraction - * @param[out] liquidComposition the calculated liquid phase composition - * @param[out] vapourComposition the calculated vapour phase composition - * @return an indicator of success of the flash - */ - template< int USD1, int USD2 > - GEOS_HOST_DEVICE - static bool compute( integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - arraySlice2d< real64, USD1 > const & kValues, - real64 & vapourPhaseMoleFraction, - arraySlice1d< real64, USD2 > const & liquidComposition, - arraySlice1d< real64, USD2 > const & vapourComposition ); - - /** - * @brief Calculate derivatives from the two-phase negative flash - * @param[in] numComps number of components - * @param[in] pressure pressure - * @param[in] temperature temperature - * @param[in] composition composition of the mixture - * @param[in] componentProperties The compositional component properties - * @param[in] flashData The parameters required for the flash - * @param[in] vapourFraction the calculated vapour (gas) mole fraction - * @param[in] liquidComposition the calculated liquid phase composition - * @param[in] vapourComposition the calculated vapour phase composition - * @param[out] vapourFractionDerivs derivatives of the calculated vapour (gas) mole fraction - * @param[out] liquidCompositionDerivs derivatives of the calculated liquid phase composition - * @param[out] vapourCompositionDerivs derivatives of the calculated vapour phase composition - */ - template< integer USD1, integer USD2, integer USD3 > - GEOS_HOST_DEVICE - static void computeDerivatives( integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - real64 const & vapourFraction, - arraySlice1d< real64 const, USD1 > const & liquidComposition, - arraySlice1d< real64 const, USD1 > const & vapourComposition, - arraySlice1d< real64, USD2 > const & vapourFractionDerivs, - arraySlice2d< real64, USD3 > const & liquidCompositionDerivs, - arraySlice2d< real64, USD3 > const & vapourCompositionDerivs ); - -private: - /** - * @brief Calculate the logarithms of the fugacity ratios - * @param[in] numComps number of components - * @param[in] pressure pressure - * @param[in] temperature temperature - * @param[in] composition composition of the mixture - * @param[in] componentProperties The compositional component properties - * @param[in] flashData The parameters required for the flash - * @param[in] kValues The k-values - * @param[in] presentComponents The indices of the present components - * @param[out] vapourPhaseMoleFraction the calculated vapour (gas) mole fraction - * @param[out] liquidComposition the calculated liquid phase composition - * @param[out] vapourComposition the calculated vapour phase composition - * @param[out] logLiquidFugacity the calculated log fugacity ratios for the liquid phase - * @param[out] logVapourFugacity the calculated log fugacity ratios for the vapour phase - * @param[out] fugacityRatios the fugacity rations - * @return The error - */ - template< integer USD1, integer USD2 > - GEOS_HOST_DEVICE - static real64 computeFugacityRatio( - integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - arraySlice1d< real64 const, USD1 > const & kValues, - arraySlice1d< integer const > const & presentComponents, - real64 & vapourPhaseMoleFraction, - arraySlice1d< real64, USD2 > const & liquidComposition, - arraySlice1d< real64, USD2 > const & vapourComposition, - arraySlice1d< real64 > const & logLiquidFugacity, - arraySlice1d< real64 > const & logVapourFugacity, - arraySlice1d< real64 > const & fugacityRatios ); - - /** - * @brief Solve the lineat system for the derivatives of the flash - * @param[in/out] A the coefficient matrix. Destroyed after call - * @param[in/out] X the rhs and solution - * @return @c true if the problem is well solved @c false otherwise - */ - template< int USD > - GEOS_HOST_DEVICE - static bool solveLinearSystem( arraySlice2d< real64, USD > const & A, - arraySlice2d< real64, USD > const & X ) - { -#if defined(GEOS_DEVICE_COMPILE) - GEOS_UNUSED_VAR( A ); - GEOS_UNUSED_VAR( X ); - return false; -#else - BlasLapackLA::solveLinearSystem( A, X ); - return true; -#endif - } - -}; - template< int USD1, int USD2 > GEOS_HOST_DEVICE bool NegativeTwoPhaseFlash::compute( integer const numComps, @@ -452,10 +327,25 @@ real64 NegativeTwoPhaseFlash::computeFugacityRatio( return LvArray::math::sqrt( error ); } +template< int USD > +GEOS_HOST_DEVICE +bool NegativeTwoPhaseFlash::solveLinearSystem( arraySlice2d< real64, USD > const & A, + arraySlice2d< real64, USD > const & X ) +{ +#if defined(GEOS_DEVICE_COMPILE) + GEOS_UNUSED_VAR( A ); + GEOS_UNUSED_VAR( X ); + return false; +#else + BlasLapackLA::solveLinearSystem( A, X ); + return true; +#endif +} + } // namespace compositional } // namespace constitutive } // namespace geos -#endif //GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_HPP_ +#endif //GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_IMPL_HPP_ From 7d8020041fdcee60cbf881e6badabdcfb5065fe0 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 17 Jul 2025 17:56:06 -0500 Subject: [PATCH 06/28] Add flash parameters --- .../functions/NegativeTwoPhaseFlash.hpp | 4 +++ .../functions/NegativeTwoPhaseFlash_impl.hpp | 24 +++++++++++------ .../models/NegativeTwoPhaseFlashModel.hpp | 2 ++ .../parameters/FlashParameters.cpp | 22 +++++++++++++++- .../parameters/FlashParameters.hpp | 26 ++++++++++++++----- .../unitTests/testNegativeTwoPhaseFlash.cpp | 12 +++++++++ .../testNegativeTwoPhaseFlash9Comp.cpp | 12 +++++++++ .../unitTests/testSoreideWhitsonFlash.cpp | 5 ++++ .../unitTests/testStabilityTest9Comp.cpp | 3 +++ 9 files changed, 94 insertions(+), 16 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp index ab620ea8345..597fd36cb40 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp @@ -45,6 +45,8 @@ struct NegativeTwoPhaseFlash * @param[in] composition composition of the mixture * @param[in] componentProperties The compositional component properties * @param[in] flashData The parameters required for the flash + * @param[in] continuousFlashParameters List of continuous (float) parameters for flash + * @param[in] discreteFlashParameters List of discrete (integer) parameters for flash * @param[in/out] kValues The phase equilibrium ratios * @param[out] vapourPhaseMoleFraction the calculated vapour (gas) mole fraction * @param[out] liquidComposition the calculated liquid phase composition @@ -59,6 +61,8 @@ struct NegativeTwoPhaseFlash arraySlice1d< real64 const > const & composition, ComponentProperties::KernelWrapper const & componentProperties, FlashData const & flashData, + arraySlice1d< real64 const > const & continuousFlashParameters, + arraySlice1d< integer const > const & discreteFlashParameters, arraySlice2d< real64, USD1 > const & kValues, real64 & vapourPhaseMoleFraction, arraySlice1d< real64, USD2 > const & liquidComposition, diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index 549328daf56..71c36c4c842 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -24,6 +24,7 @@ #include "KValueInitialization.hpp" #include "FugacityCalculator.hpp" #include "Utilities.hpp" +#include "constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp" #include "denseLinearAlgebra/interfaces/blaslapack/BlasLapackLA.hpp" namespace geos @@ -42,15 +43,18 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, arraySlice1d< real64 const > const & composition, ComponentProperties::KernelWrapper const & componentProperties, FlashData const & flashData, + arraySlice1d< real64 const > const & continuousFlashParameters, + arraySlice1d< integer const > const & discreteFlashParameters, arraySlice2d< real64, USD1 > const & kValues, real64 & vapourPhaseMoleFraction, arraySlice1d< real64, USD2 > const & liquidComposition, arraySlice1d< real64, USD2 > const & vapourComposition ) { constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; - stackArray1d< real64, maxNumComps > logLiquidFugacity( numComps ); - stackArray1d< real64, maxNumComps > logVapourFugacity( numComps ); - stackArray1d< real64, maxNumComps > fugacityRatios( numComps ); + StackArray< real64, 2, 3*maxNumComps > workSpace( 3, maxNumComps ); + arraySlice1d< real64 > logLiquidFugacity = workSpace[0]; + arraySlice1d< real64 > logVapourFugacity = workSpace[1]; + arraySlice1d< real64 > fugacityRatios = workSpace[2]; stackArray1d< integer, maxNumComps > componentIndices( numComps ); auto const & kVapourLiquid = kValues[0]; @@ -58,6 +62,10 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, auto const presentComponents = componentIndices.toSliceConst(); + // Extract flash parameters + integer const maxIterations = discreteFlashParameters[FlashParameters::FLASH_MAX_ITERATIONS]; + real64 const flashTolerance = continuousFlashParameters[FlashParameters::FLASH_TOLERANCE]; + // Initialise compositions to feed composition for( integer ic = 0; ic < numComps; ++ic ) { @@ -66,7 +74,7 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, } bool converged = false; - for( localIndex iterationCount = 0; iterationCount < MultiFluidConstants::maxSSIIterations; ++iterationCount ) + for( localIndex iterationCount = 0; iterationCount < maxIterations; ++iterationCount ) { real64 const error = computeFugacityRatio( numComps, pressure, @@ -79,12 +87,12 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, vapourPhaseMoleFraction, liquidComposition, vapourComposition, - logLiquidFugacity.toSlice(), - logVapourFugacity.toSlice(), - fugacityRatios.toSlice() ); + logLiquidFugacity, + logVapourFugacity, + fugacityRatios ); // Compute fugacity ratios and check convergence - converged = (error < MultiFluidConstants::fugacityTolerance); + converged = (error < flashTolerance); if( converged ) { diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp index dc9b6eb78c8..1e702e4f768 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp @@ -126,6 +126,8 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate compFraction, componentProperties, m_flashData, + m_continuousFlashParameters.toSliceConst(), + m_discreteFlashParameters.toSliceConst(), kValues, phaseFraction.value[m_vapourIndex], phaseCompFraction.value[m_liquidIndex], diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp index b8a236256f2..9fa95761b7a 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp @@ -38,8 +38,10 @@ FlashParameters::FlashParameters( std::unique_ptr< ModelParameters > parameters { m_continuousParameters[STABILITY_THRESHOLD] = -1.0e-8; m_continuousParameters[STABILITY_TOLERANCE] = 1.0e-8; + m_continuousParameters[FLASH_TOLERANCE] = 1.0e-8; m_discreteParameters[STABILITY_MAX_ITERATIONS] = 300; + m_discreteParameters[FLASH_MAX_ITERATIONS] = 300; } std::unique_ptr< ModelParameters > FlashParameters::create( std::unique_ptr< ModelParameters > parameters ) @@ -67,6 +69,16 @@ void FlashParameters::registerParametersImpl( MultiFluidBase * fluid ) setInputFlag( dataRepository::InputFlags::OPTIONAL ). setDefaultValue( m_discreteParameters[STABILITY_MAX_ITERATIONS] ). setDescription( "The maximum number of successive substitution iterations used during the stability test" ); + + fluid->registerWrapper( viewKeyStruct::flashMaxIterationsString(), &m_discreteParameters[FLASH_MAX_ITERATIONS] ). + setInputFlag( dataRepository::InputFlags::OPTIONAL ). + setDefaultValue( m_discreteParameters[FLASH_MAX_ITERATIONS] ). + setDescription( "The maximum number of iterations used during the flash" ); + + fluid->registerWrapper( viewKeyStruct::flashToleranceString(), &m_continuousParameters[FLASH_TOLERANCE] ). + setInputFlag( dataRepository::InputFlags::OPTIONAL ). + setDefaultValue( m_continuousParameters[FLASH_TOLERANCE] ). + setDescription( "The tolerance to use to determine convergece of the flash" ); } void FlashParameters::postInputInitializationImpl( MultiFluidBase const * fluid, @@ -101,9 +113,17 @@ void FlashParameters::postInputInitializationImpl( MultiFluidBase const * fluid, real64 const stabilityTolerance = m_continuousParameters[STABILITY_TOLERANCE]; checkLowerBound( stabilityTolerance, epsilon, viewKeyStruct::stabilityThresholdString() ); - // Max number of iterations should be at least 1 + // Max number of stability iterations should be at least 1 integer const stabilityMaxIterations = m_discreteParameters[STABILITY_MAX_ITERATIONS]; checkLowerBound( stabilityMaxIterations, 1, viewKeyStruct::stabilityMaxIterationsString() ); + + // Flash tolerance should be positive + real64 const flashTolerance = m_continuousParameters[FLASH_TOLERANCE]; + checkLowerBound( flashTolerance, epsilon, viewKeyStruct::flashToleranceString() ); + + // Max number of flash iterations should be at least 1 + integer const flashMaxIterations = m_discreteParameters[FLASH_MAX_ITERATIONS]; + checkLowerBound( flashMaxIterations, 1, viewKeyStruct::flashMaxIterationsString() ); } } // end namespace compositional diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp index 6f121ea5adb..5e51237c642 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp @@ -39,19 +39,29 @@ class FlashParameters : public ModelParameters * Flash variables * These are indices into an array that holds the actual values */ - /** The value of the tangent plane distance below which a mixture is determined to be unstable. */ - static integer constexpr STABILITY_THRESHOLD = 0; + + // --- integer parameters --- + /** The maximum number of iterations used during the flash. */ + static integer constexpr FLASH_MAX_ITERATIONS = 0; /** The maximum number of iterations used during the stability test. */ - static integer constexpr STABILITY_MAX_ITERATIONS = 0; + static integer constexpr STABILITY_MAX_ITERATIONS = 1; + + /* Number of discrete variables */ + static integer constexpr NUM_INTEGER = 2; + + // --- real parameters --- + /** The tolerance to use to determine convergece of the flash. */ + static integer constexpr FLASH_TOLERANCE = 0; + + /** The value of the tangent plane distance below which a mixture is determined to be unstable. */ + static integer constexpr STABILITY_THRESHOLD = 1; /** The tolerance to use to determine convergece to a stationary point in the stability test. */ - static integer constexpr STABILITY_TOLERANCE = 1; + static integer constexpr STABILITY_TOLERANCE = 2; /* Number of continuous variables */ - static integer constexpr NUM_FLOAT = 2; - /* Number of discrete variables */ - static integer constexpr NUM_INTEGER = 1; + static integer constexpr NUM_FLOAT = 3; public: FlashParameters( std::unique_ptr< ModelParameters > parameters ); @@ -61,6 +71,8 @@ class FlashParameters : public ModelParameters struct viewKeyStruct { + static constexpr char const * flashToleranceString() { return "flashTolerance"; } + static constexpr char const * flashMaxIterationsString() { return "flashMaxIterations"; } static constexpr char const * stabilityThresholdString() { return "stabilityThreshold"; } static constexpr char const * stabilityToleranceString() { return "stabilityTolerance"; } static constexpr char const * stabilityMaxIterationsString() { return "stabilityMaxIterations"; } diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash.cpp index 510439404d8..0680bf91686 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash.cpp @@ -107,6 +107,9 @@ class NegativeTwoPhaseFlashTestFixture : public ::testing::TestWithParam< Flash componentProperties, kValues[0] ); + auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); + auto const * flashParameters = parameters->get< FlashParameters >(); + bool status = NegativeTwoPhaseFlash::compute( numComps, pressure, @@ -114,6 +117,8 @@ class NegativeTwoPhaseFlashTestFixture : public ::testing::TestWithParam< Flash composition.toSliceConst(), componentProperties, flashData, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, kValues.toSlice(), vapourFraction, liquidComposition, @@ -176,6 +181,9 @@ class NegativeTwoPhaseFlashTestFixture : public ::testing::TestWithParam< Flash componentProperties, kValues[0] ); + auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); + auto const * flashParameters = parameters->get< FlashParameters >(); + stackArray1d< real64, numDofs > vapourFractionDerivs( numDofs ); stackArray2d< real64, numComps * numDofs > liquidCompositionDerivs( numComps, numDofs ); stackArray2d< real64, numComps * numDofs > vapourCompositionDerivs( numComps, numDofs ); @@ -208,6 +216,8 @@ class NegativeTwoPhaseFlashTestFixture : public ::testing::TestWithParam< Flash zmf.toSliceConst(), componentProperties, flashData, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, kValues.toSlice(), values[0], displacedLiquidComposition.toSlice(), @@ -226,6 +236,8 @@ class NegativeTwoPhaseFlashTestFixture : public ::testing::TestWithParam< Flash composition.toSliceConst(), componentProperties, flashData, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, kValues.toSlice(), vapourFraction, liquidComposition.toSlice(), diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp index 89d4cd1b0df..bd751e0fac9 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp @@ -88,6 +88,9 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< componentProperties, kValues[0] ); + auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); + auto const * flashParameters = parameters->get< FlashParameters >(); + bool status = NegativeTwoPhaseFlash::compute( numComps, pressure, @@ -95,6 +98,8 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< composition.toSliceConst(), componentProperties, flashData, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, kValues.toSlice(), vapourFraction, liquidComposition.toSlice(), @@ -156,6 +161,9 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< componentProperties, kValues[0] ); + auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); + auto const * flashParameters = parameters->get< FlashParameters >(); + stackArray1d< real64, numDofs > vapourFractionDerivs( numDofs ); stackArray2d< real64, numComps * numDofs > liquidCompositionDerivs( numComps, numDofs ); stackArray2d< real64, numComps * numDofs > vapourCompositionDerivs( numComps, numDofs ); @@ -188,6 +196,8 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< zmf.toSliceConst(), componentProperties, flashData, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, kValues.toSlice(), values[0], displacedLiquidComposition.toSlice(), @@ -206,6 +216,8 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< composition.toSliceConst(), componentProperties, flashData, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, kValues.toSlice(), vapourFraction, liquidComposition.toSlice(), diff --git a/src/coreComponents/constitutive/unitTests/testSoreideWhitsonFlash.cpp b/src/coreComponents/constitutive/unitTests/testSoreideWhitsonFlash.cpp index 9fb21d2136d..54645b4207e 100644 --- a/src/coreComponents/constitutive/unitTests/testSoreideWhitsonFlash.cpp +++ b/src/coreComponents/constitutive/unitTests/testSoreideWhitsonFlash.cpp @@ -117,6 +117,9 @@ TEST_P( SoreideWhitsonSolubilityTestFixture, testSolubility ) kValues( 0, 0 ) = 100.0; kValues( 0, 1 ) = 0.01; + auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); + auto const * flashParameters = parameters->get< FlashParameters >(); + bool status = NegativeTwoPhaseFlash::compute( numComps, pressure, @@ -124,6 +127,8 @@ TEST_P( SoreideWhitsonSolubilityTestFixture, testSolubility ) totalComposition.toSliceConst(), componentProperties, flashData, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, kValues.toSlice(), vapourFraction, liquidComposition, diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp index d9d8f645362..88ca5aba8c6 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp @@ -118,6 +118,7 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat temperature, componentProperties, kValues[0] ); + auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); auto const * flashParameters = parameters->get< FlashParameters >(); @@ -145,6 +146,8 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat composition.toSliceConst(), componentProperties, flashData, + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, kValues.toSlice(), vapourFraction, liquidComposition.toSlice(), From d074c2d17e01a7aeb9bca2edd3284564457a2580 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Fri, 18 Jul 2025 15:46:43 -0500 Subject: [PATCH 07/28] Add stability derivatives --- .../functions/NegativeTwoPhaseFlash.hpp | 12 -- .../functions/NegativeTwoPhaseFlash_impl.hpp | 20 +- .../compositional/functions/StabilityTest.hpp | 175 ++++++++++++++++-- .../compositional/functions/Utilities.hpp | 22 +++ .../models/NegativeTwoPhaseFlashModel.hpp | 105 +++++++---- .../parameters/FlashParameters.cpp | 7 +- .../unitTests/TestFluidUtilities.hpp | 15 +- .../testImmiscibleWaterFlashModel.cpp | 2 +- .../testNegativeTwoPhaseFlashModel.cpp | 138 +++++++------- .../unitTests/testStabilityTest2Comp.cpp | 4 +- .../unitTests/testStabilityTest9Comp.cpp | 8 +- 11 files changed, 346 insertions(+), 162 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp index 597fd36cb40..a51cf561472 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp @@ -134,18 +134,6 @@ struct NegativeTwoPhaseFlash arraySlice1d< real64 > const & logLiquidFugacity, arraySlice1d< real64 > const & logVapourFugacity, arraySlice1d< real64 > const & fugacityRatios ); - - /** - * @brief Solve the lineat system for the derivatives of the flash - * @param[in/out] A the coefficient matrix. Destroyed after call - * @param[in/out] X the rhs and solution - * @return @c true if the problem is well solved @c false otherwise - */ - template< int USD > - GEOS_HOST_DEVICE - static bool solveLinearSystem( arraySlice2d< real64, USD > const & A, - arraySlice2d< real64, USD > const & X ); - }; } // namespace compositional diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index 71c36c4c842..be98d2ff301 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -25,7 +25,6 @@ #include "FugacityCalculator.hpp" #include "Utilities.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp" -#include "denseLinearAlgebra/interfaces/blaslapack/BlasLapackLA.hpp" namespace geos { @@ -50,6 +49,8 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, arraySlice1d< real64, USD2 > const & liquidComposition, arraySlice1d< real64, USD2 > const & vapourComposition ) { + GEOS_MARK_FUNCTION; + constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; StackArray< real64, 2, 3*maxNumComps > workSpace( 3, maxNumComps ); arraySlice1d< real64 > logLiquidFugacity = workSpace[0]; @@ -145,6 +146,8 @@ void NegativeTwoPhaseFlash::computeDerivatives( arraySlice2d< real64, USD3 > const & liquidCompositionDerivs, arraySlice2d< real64, USD3 > const & vapourCompositionDerivs ) { + GEOS_MARK_FUNCTION; + constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; constexpr integer maxNumDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; @@ -335,21 +338,6 @@ real64 NegativeTwoPhaseFlash::computeFugacityRatio( return LvArray::math::sqrt( error ); } -template< int USD > -GEOS_HOST_DEVICE -bool NegativeTwoPhaseFlash::solveLinearSystem( arraySlice2d< real64, USD > const & A, - arraySlice2d< real64, USD > const & X ) -{ -#if defined(GEOS_DEVICE_COMPILE) - GEOS_UNUSED_VAR( A ); - GEOS_UNUSED_VAR( X ); - return false; -#else - BlasLapackLA::solveLinearSystem( A, X ); - return true; -#endif -} - } // namespace compositional } // namespace constitutive diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp index d807c408112..ece509ab512 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp @@ -28,6 +28,7 @@ #include "constitutive/fluid/multifluid/compositional/parameters/ComponentProperties.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp" #include "constitutive/fluid/multifluid/compositional/functions/FlashData.hpp" +#include "common/TimingMacros.hpp" namespace geos { @@ -42,6 +43,7 @@ struct StabilityTest { private: static constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; + using Deriv = constitutive::multifluid::DerivativeOffset; public: /** * @brief Perform a two-phase stability test @@ -52,11 +54,14 @@ struct StabilityTest * @param[in] componentProperties The compositional component properties * @param[in] equationOfState The equation of state * @param[in] flashData The parameters required for the flash + * @param[in] kValues the k-values to use to create test samples * @param[in] continuousFlashParameters List of continuous (float) parameters for flash * @param[in] discreteFlashParameters List of discrete (integer) parameters for flash * @param[out] tangentPlaneDistance the minimum tangent plane distance (TPD) - * @param[out] kValues the k-values estimated from the stationary points - * @return a flag indicating that 2 stationary points have been found + * @param[out] incipientComposition The composition of the incipient phase. This will be + * set to the incipient phase composition at the stationary point that is furthest + * from the trivial solution. + * @return a flag indicating that mixture is unstable or all test points converged */ template< integer USD1, integer USD2 > GEOS_HOST_DEVICE @@ -67,11 +72,14 @@ struct StabilityTest ComponentProperties::KernelWrapper const & componentProperties, EquationOfStateType const & equationOfState, FlashData const & flashData, + arraySlice1d< real64 const, USD2 > const & kValues, arraySlice1d< real64 const > const & continuousFlashParameters, arraySlice1d< integer const > const & discreteFlashParameters, real64 & tangentPlaneDistance, - arraySlice1d< real64, USD2 > const & kValues ) + arraySlice1d< real64 > const & incipientComposition ) { + GEOS_MARK_FUNCTION; + stackArray2d< real64, 4*maxNumComps > workSpace( 4, numComps ); arraySlice1d< real64 > logFugacity = workSpace[0]; arraySlice1d< real64 > normalizedComposition = workSpace[1]; @@ -79,10 +87,11 @@ struct StabilityTest arraySlice1d< real64 > hyperplane = workSpace[3]; // h-parameter stackArray1d< integer, maxNumComps > availableComponents( numComps ); + //integer const presentCount = calculatePresentComponents( numComps, composition, availableComponents ); auto const presentComponents = availableComponents.toSliceConst(); - LvArray::forValuesInSlice( workSpace.toSlice(), []( real64 & a ){ a = 0.0; } ); + LvArray::forValuesInSlice( workSpace.toSlice(), setZero ); // Extract flash parameters integer const maxIterations = discreteFlashParameters[FlashParameters::STABILITY_MAX_ITERATIONS]; @@ -110,7 +119,10 @@ struct StabilityTest // Flag to indicate all trial compositions converged bool allConverged = true; - for( real64 const alpha : { 1.0, -1.0, 3.0, -3.0 } ) + // Measure of distance to trivial solution + real64 maxDistanceToTrivialSolution = 0.0; + + for( real64 const alpha : { 1.0, -1.0 } ) { // Initialise next sample for( integer const ic : presentComponents ) @@ -118,7 +130,6 @@ struct StabilityTest logTrialComposition[ic] = LvArray::math::log( composition[ic] ) + alpha*LvArray::math::log( kValues[ic] ); normalizedComposition[ic] = LvArray::math::exp( logTrialComposition[ic] ); } - // Start iterations for this sample bool converged = false; for( localIndex iterationCount = 0; iterationCount < maxIterations; ++iterationCount ) @@ -134,30 +145,30 @@ struct StabilityTest flashData, logFugacity ); - // Calculate the TPD + // Calculate the TPD and stationarity real64 tpd = 0.0; + real64 error = 0.0; for( integer const ic : presentComponents ) { - tpd += composition[ic] + totalMoles * normalizedComposition[ic] * (logTrialComposition[ic] + logFugacity[ic] - hyperplane[ic] - 1.0); + real64 const dG = logTrialComposition[ic] + logFugacity[ic] - hyperplane[ic]; + tpd += composition[ic] + totalMoles * normalizedComposition[ic] * (dG - 1.0); + error += (dG*dG); } + error = LvArray::math::sqrt( error ); if( tpd < tangentPlaneDistance ) { tangentPlaneDistance = tpd; } - if( tangentPlaneDistance < stabilityThreshold ) - { - converged = true; - break; - } + std::cout + << std::fixed << std::setprecision( 1 ) << std::setw( 4 ) << alpha << " " + << std::setw( 3 ) << iterationCount << " " + << std::fixed << std::setprecision( 6 ) << std::setw( 4 ) << normalizedComposition << " " + << std::scientific << std::setprecision( 6 ) << logFugacity << " " + << std::scientific << std::setprecision( 6 ) << std::setw( 13 ) << tpd << " " + << std::scientific << std::setprecision( 6 ) << std::setw( 13 ) << error << " " + << "\n"; // Check stationarity - real64 error = 0.0; - for( integer const ic : presentComponents ) - { - real64 const dG = logTrialComposition[ic] + logFugacity[ic] - hyperplane[ic]; - error += (dG*dG); - } - error = LvArray::math::sqrt( error ); if( error < stabilityTolerance ) { converged = true; @@ -172,14 +183,138 @@ struct StabilityTest } } allConverged = allConverged && converged; + + // Calculate the distance to the trivial solution + real64 distance = 0.0; + for( integer const ic : presentComponents ) + { + real64 const dZ = normalizedComposition[ic] - composition[ic]; + distance += (dZ*dZ); + } + if( maxDistanceToTrivialSolution < distance ) + { + maxDistanceToTrivialSolution = distance; + for( integer ic = 0; ic < numComps; ++ic ) + { + incipientComposition[ic] = normalizedComposition[ic]; + } + } if( tangentPlaneDistance < stabilityThreshold ) { break; } } + // The test is successful if either we have a negative TPD or all test compositions converged to stationarity return (tangentPlaneDistance < stabilityThreshold) || (allConverged); } + + /** + * @brief Compute derivatives of the incipient phase composition + * @param[in] numComps number of components + * @param[in] pressure pressure + * @param[in] temperature temperature + * @param[in] composition composition of the mixture + * @param[in] componentProperties The compositional component properties + * @param[in] equationOfState The equation of state + * @param[in] flashData The parameters required for the flash + * @param[in] incipientComposition The composition of the incipient phase + * @param[out] incipientCompositionDerivs Derivatives of the composition of the incipient phase + * @param[out] compositionDerivs Workspace + */ + template< integer USD1, integer USD2 > + GEOS_HOST_DEVICE + static void computeDerivatives( integer const numComps, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, USD1 > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + EquationOfStateType const & equationOfState, + FlashData const & flashData, + arraySlice1d< real64 const > const & incipientComposition, + arraySlice2d< real64, USD2 > const & incipientCompositionDerivs, + arraySlice2d< real64, USD2 > const & compositionDerivs ) + { + GEOS_MARK_FUNCTION; + + integer constexpr maxNumRows = MultiFluidConstants::MAX_NUM_COMPONENTS + 1; + integer constexpr maxDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; + + integer const numDofs = 2 + numComps; + + StackArray< real64, 1, maxNumComps > logFugacity( numComps ); + auto const & logFugacityIncipientDerivs = incipientCompositionDerivs; + auto const & logFugacitySampleDerivs = compositionDerivs; + + FugacityCalculator::computeLogFugacityDerivatives( numComps, + pressure, + temperature, + composition, + componentProperties, + equationOfState, + flashData, + logFugacity.toSlice(), + logFugacitySampleDerivs ); + FugacityCalculator::computeLogFugacityDerivatives( numComps, + pressure, + temperature, + incipientComposition, + componentProperties, + equationOfState, + flashData, + logFugacity.toSlice(), + logFugacityIncipientDerivs ); + + StackArray< real64, 2, maxNumRows * maxNumRows, MatrixLayout::COL_MAJOR_PERM > A( numComps + 1, numComps + 1 ); + StackArray< real64, 2, maxNumRows * maxDofs, MatrixLayout::COL_MAJOR_PERM > X( numComps + 1, numDofs ); + + for( integer ic = 0; ic < numComps; ++ic ) + { + real64 const yi = incipientComposition[ic]; + for( integer jc = 0; jc < numComps; ++jc ) + { + real64 const df_dyj = logFugacityIncipientDerivs( ic, Deriv::dC+jc ); + A( ic, jc ) = yi*df_dyj; + } + A( ic, ic ) += 1.0; + A( ic, numComps ) = yi; + A( numComps, ic ) = 1.0; + } + A( numComps, numComps ) = 0.0; + + for( integer ic = 0; ic < numComps; ++ic ) + { + real64 const yi = incipientComposition[ic]; + for( integer const idof : {Deriv::dP, Deriv::dT} ) + { + X( ic, idof ) = yi*(-logFugacityIncipientDerivs( ic, idof ) + logFugacitySampleDerivs( ic, idof )); + } + for( integer jc = 0; jc < numComps; ++jc ) + { + integer const idof = Deriv::dC + jc; + X( ic, idof ) = yi*logFugacitySampleDerivs( ic, idof ); + } + if( MultiFluidConstants::epsilon < composition[ic] ) + { + X( ic, Deriv::dC+ic ) += yi/composition[ic]; + } + } + for( integer idof = 0; idof < numDofs; ++idof ) + { + X( numComps, idof ) = 0.0; + } + + // Solve linear system + solveLinearSystem( A.toSlice(), X.toSlice() ); + + for( integer idof = 0; idof < numDofs; ++idof ) + { + for( integer ic = 0; ic < numComps; ++ic ) + { + incipientCompositionDerivs( ic, idof ) = X( ic, idof ); + } + } + } }; } // namespace compositional diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp index 224081b8e7f..e5b7d9199cf 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp @@ -21,6 +21,7 @@ #define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_UTILITIES_HPP_ #include "constitutive/fluid/multifluid/MultiFluidConstants.hpp" +#include "denseLinearAlgebra/interfaces/blaslapack/BlasLapackLA.hpp" namespace geos { @@ -111,6 +112,27 @@ static integer calculatePresentComponents( integer const numComps, return presentCount; } +/** + * @brief Solve the lineat system for the derivatives of the flash + * @param[in/out] A the coefficient matrix. Destroyed after call + * @param[in/out] X the rhs and solution + * @return @c true if the problem is well solved @c false otherwise + */ +template< int USD > +GEOS_HOST_DEVICE +static bool solveLinearSystem( arraySlice2d< real64, USD > const & A, + arraySlice2d< real64, USD > const & X ) +{ +#if defined(GEOS_DEVICE_COMPILE) + GEOS_UNUSED_VAR( A ); + GEOS_UNUSED_VAR( X ); + return false; +#else + BlasLapackLA::solveLinearSystem( A, X ); + return true; +#endif +} + } // namespace compositional } // namespace constitutive } // namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp index 1e702e4f768..5dd19b861f3 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp @@ -43,6 +43,10 @@ class ModelParameters; class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate { +private: + // Tolerance on temperature for phase labelling + static constexpr real64 temperatureTolerance = 0.1; + public: using PhaseProp = MultiFluidVar< real64, 3, constitutive::multifluid::LAYOUT_PHASE, constitutive::multifluid::LAYOUT_PHASE_DC >; using PhaseComp = MultiFluidVar< real64, 4, constitutive::multifluid::LAYOUT_PHASE_COMP, constitutive::multifluid::LAYOUT_PHASE_COMP_DC >; @@ -72,8 +76,12 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate PhaseProp::SliceType const phaseFraction, PhaseComp::SliceType const phaseCompFraction ) const { + constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; + integer const numDofs = 2 + m_numComponents; + stackArray1d< real64, maxNumComps > incipientComposition( m_numComponents ); + // Check if k-Values need to be initialised auto kVapourLiquid = kValues[0]; bool const needInitialisation = hasZero( m_numComponents, kVapourLiquid.toSliceConst() ); @@ -101,18 +109,24 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate } // Perform stability test to check that we have 2 phases + integer const stabilityIterations = m_discreteFlashParameters[FlashParameters::STABILITY_MAX_ITERATIONS]; real64 tangentPlaneDistance = 0.0; - bool const stabilityStatus = StabilityTest::compute( m_numComponents, - pressure, - temperature, - compFraction, - componentProperties, - m_flashData.liquidEos, - m_flashData, - m_continuousFlashParameters.toSliceConst(), - m_discreteFlashParameters.toSliceConst(), - tangentPlaneDistance, - kValues[0] ); + bool stabilityStatus = false; + if( 0 < stabilityIterations || needInitialisation ) + { + stabilityStatus = StabilityTest::compute( m_numComponents, + pressure, + temperature, + compFraction, + componentProperties, + m_flashData.liquidEos, + m_flashData, + kVapourLiquid.toSliceConst(), + m_continuousFlashParameters.toSliceConst(), + m_discreteFlashParameters.toSliceConst(), + tangentPlaneDistance, + incipientComposition.toSlice() ); + } // If the stability test failed to converge to a stationary point then we will assume the mixture is unstable real64 const stabilityThreshold = m_continuousFlashParameters[FlashParameters::STABILITY_THRESHOLD]; @@ -154,20 +168,53 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate else { // Stable mixture - simply label - calculateLiCorrelation( componentProperties, - temperature, - compFraction, - phaseFraction.value[m_vapourIndex] ); + // The gas phase has a lower Li-temperature + real64 const sampleTemperature = calculateLiTemperature( componentProperties, compFraction ); + real64 const incipientTemperature = calculateLiTemperature( componentProperties, incipientComposition.toSliceConst()); + + int sampleIndex = m_liquidIndex; + int incipientIndex = m_vapourIndex; + if( sampleTemperature < incipientTemperature - temperatureTolerance ) + { + sampleIndex = m_vapourIndex; + incipientIndex = m_liquidIndex; + } + else if( incipientTemperature < sampleTemperature - temperatureTolerance ) + { + /* Do nothing */ + } + else if( sampleTemperature < temperature ) + { + sampleIndex = m_vapourIndex; + incipientIndex = m_liquidIndex; + } + std::cout << "LI " << sampleTemperature << " " << incipientTemperature << " " << incipientTemperature-sampleTemperature << " " + << "{" << sampleIndex << ", " << incipientIndex << "} " + << "{" << m_liquidIndex << ", " << m_vapourIndex << "} " + << "\n"; + + phaseFraction.value[m_vapourIndex] = (sampleIndex == m_vapourIndex) ? 1.0 : 0.0; LvArray::forValuesInSlice( phaseFraction.derivs[m_vapourIndex], setZero ); - LvArray::forValuesInSlice( phaseCompFraction.derivs[m_liquidIndex], setZero ); - LvArray::forValuesInSlice( phaseCompFraction.derivs[m_vapourIndex], setZero ); + + StabilityTest::computeDerivatives( m_numComponents, + pressure, + temperature, + compFraction, + componentProperties, + m_flashData.liquidEos, + m_flashData, + incipientComposition.toSliceConst(), + phaseCompFraction.derivs[incipientIndex], + phaseCompFraction.derivs[sampleIndex] ); + + LvArray::forValuesInSlice( phaseCompFraction.derivs[sampleIndex], setZero ); for( integer ic = 0; ic < m_numComponents; ++ic ) { - phaseCompFraction.value( m_vapourIndex, ic ) = compFraction[ic]; - phaseCompFraction.value( m_liquidIndex, ic ) = compFraction[ic]; - phaseCompFraction.derivs( m_vapourIndex, ic, Deriv::dC + ic ) = 1.0; - phaseCompFraction.derivs( m_liquidIndex, ic, Deriv::dC + ic ) = 1.0; + phaseCompFraction.value( sampleIndex, ic ) = compFraction[ic]; + phaseCompFraction.derivs( sampleIndex, ic, Deriv::dC + ic ) = 1.0; + + phaseCompFraction.value( incipientIndex, ic ) = incipientComposition[ic]; } } @@ -181,10 +228,8 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate template< int USD > GEOS_HOST_DEVICE - void calculateLiCorrelation( ComponentProperties::KernelWrapper const & componentProperties, - real64 const & temperature, - arraySlice1d< real64 const, USD > const & composition, - real64 & vapourFraction ) const + real64 calculateLiTemperature( ComponentProperties::KernelWrapper const & componentProperties, + arraySlice1d< real64 const, USD > const & composition ) const { real64 sumVz = 0.0; real64 sumVzt = 0.0; @@ -195,15 +240,7 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate sumVz += Vz; sumVzt += Vz * criticalTemperature[ic]; } - real64 const pseudoCritTemperature = sumVzt / sumVz; - if( pseudoCritTemperature < temperature ) - { - vapourFraction = 1.0; - } - else - { - vapourFraction = 0.0; - } + return sumVzt / sumVz; } private: diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp index 9fa95761b7a..c6e9159800e 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp @@ -68,7 +68,8 @@ void FlashParameters::registerParametersImpl( MultiFluidBase * fluid ) fluid->registerWrapper( viewKeyStruct::stabilityMaxIterationsString(), &m_discreteParameters[STABILITY_MAX_ITERATIONS] ). setInputFlag( dataRepository::InputFlags::OPTIONAL ). setDefaultValue( m_discreteParameters[STABILITY_MAX_ITERATIONS] ). - setDescription( "The maximum number of successive substitution iterations used during the stability test" ); + setDescription( "The maximum number of successive substitution iterations used during the stability test. " + "A zero or negative value skips the stability test" ); fluid->registerWrapper( viewKeyStruct::flashMaxIterationsString(), &m_discreteParameters[FLASH_MAX_ITERATIONS] ). setInputFlag( dataRepository::InputFlags::OPTIONAL ). @@ -113,10 +114,6 @@ void FlashParameters::postInputInitializationImpl( MultiFluidBase const * fluid, real64 const stabilityTolerance = m_continuousParameters[STABILITY_TOLERANCE]; checkLowerBound( stabilityTolerance, epsilon, viewKeyStruct::stabilityThresholdString() ); - // Max number of stability iterations should be at least 1 - integer const stabilityMaxIterations = m_discreteParameters[STABILITY_MAX_ITERATIONS]; - checkLowerBound( stabilityMaxIterations, 1, viewKeyStruct::stabilityMaxIterationsString() ); - // Flash tolerance should be positive real64 const flashTolerance = m_continuousParameters[FLASH_TOLERANCE]; checkLowerBound( flashTolerance, epsilon, viewKeyStruct::flashToleranceString() ); diff --git a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp index 80aae8c1932..f5b2a2761a5 100644 --- a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp +++ b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp @@ -108,9 +108,20 @@ void testNumericalDerivative( real64 const x, selectedDerivative = deriv; } } - checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, - GEOS_FMT( "Numerical derivative for component {}", i ) ); + ((void)absTolerance); + ((void)relTolerance); + //checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, + // GEOS_FMT( "Numerical derivative for component {}", i ) ); + std::cout << std::setw( 2 ) << i << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 13 ) << derivatives[i] << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 13 ) << selectedDerivative << " | " + << std::scientific << std::setprecision( 5 ) << std::setw( 13 ) << derivatives[i]-selectedDerivative << " | " + << std::scientific << std::setprecision( 5 ) << std::setw( 13 ) << leftValues[i] << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 13 ) << centreValues[i] << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 13 ) << rightValues[i] << " " + << "\n"; } + std::cout << "-----------------------------------------------------------------------\n"; } /** diff --git a/src/coreComponents/constitutive/unitTests/testImmiscibleWaterFlashModel.cpp b/src/coreComponents/constitutive/unitTests/testImmiscibleWaterFlashModel.cpp index 6ecc3545c18..3387eb8495f 100644 --- a/src/coreComponents/constitutive/unitTests/testImmiscibleWaterFlashModel.cpp +++ b/src/coreComponents/constitutive/unitTests/testImmiscibleWaterFlashModel.cpp @@ -105,7 +105,7 @@ class ImmiscibleWaterFlashModelTestFixture : public ::testing::TestWithParam< F equationOfState->m_equationsOfStateNames.emplace_back( eosName ); auto * criticalVolume = const_cast< CriticalVolume * >(m_parameters->get< CriticalVolume >()); - TestFluid< NC >::createArray( criticalVolume->m_componentCriticalVolume, this->m_fluid->criticalVolume ); + TestFluid< NC >::populateArray( criticalVolume->m_componentCriticalVolume, this->m_fluid->criticalVolume ); m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::VAPOUR)); diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp index 4289f6a6015..de3e690fffe 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp @@ -18,6 +18,7 @@ #include "constitutive/fluid/multifluid/MultiFluidUtils.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/EquationOfState.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/CriticalVolume.hpp" +#include "constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp" #include "constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/PhaseType.hpp" #include "TestFluid.hpp" @@ -60,6 +61,19 @@ struct FluidData< 3 > } }; +template<> +struct FluidData< 4 > +{ + static constexpr integer testComponents[numTestComps] = {0, 1, 3}; + static std::unique_ptr< TestFluid< 4 > > createFluid() + { + auto fluid = TestFluid< 4 >::create( {Fluid::CH4, Fluid::CO2, Fluid::N2, Fluid::H2O} ); + const std::array< real64 const, 6 > bics = { 0.0, 0.0, 0.0, 0.4850, 0.1896, 0.4778 }; + fluid->setBinaryCoefficients( bics ); + return fluid; + } +}; + template<> struct FluidData< 9 > { @@ -76,7 +90,7 @@ struct FluidData< 9 > } }; -template< integer NC > +template< integer NC, EquationOfStateType EOS = EquationOfStateType::PengRobinson > class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< FlashData< NC > > { static constexpr real64 relTol = 1.0e-5; @@ -88,6 +102,10 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< using PhasePropSlice = NegativeTwoPhaseFlashModelUpdate::PhaseProp::SliceType; using PhaseCompSlice = NegativeTwoPhaseFlashModelUpdate::PhaseComp::SliceType; + using CompProp = StackArray< real64, 3, numPhases, multifluid::LAYOUT_PHASE >; + using PhaseProp = StackArray< real64, 4, numPhases *numDofs, multifluid::LAYOUT_PHASE_DC >; + using PhaseComp = StackArray< real64, 5, numPhases *numComps *numDofs, multifluid::LAYOUT_PHASE_COMP_DC >; + public: NegativeTwoPhaseFlashModelTestFixture() : m_fluid( FluidData< NC >::createFluid() ) @@ -97,17 +115,21 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< m_parameters = NegativeTwoPhaseFlashModel::createParameters( std::move( m_parameters ) ); auto * equationOfState = const_cast< EquationOfState * >(m_parameters->get< EquationOfState >()); - string const eosName = EnumStrings< EquationOfStateType >::toString( EquationOfStateType::PengRobinson ); + string eosName = EnumStrings< EquationOfStateType >::toString( EOS ); equationOfState->m_equationsOfStateNames.emplace_back( eosName ); + eosName = EnumStrings< EquationOfStateType >::toString( EquationOfStateType::PengRobinson ); equationOfState->m_equationsOfStateNames.emplace_back( eosName ); auto * criticalVolume = const_cast< CriticalVolume * >(m_parameters->get< CriticalVolume >()); criticalVolume->m_componentCriticalVolume.resize( numComps ); - TestFluid< NC >::createArray( criticalVolume->m_componentCriticalVolume, this->m_fluid->criticalVolume ); + TestFluid< NC >::populateArray( criticalVolume->m_componentCriticalVolume, this->m_fluid->criticalVolume ); -m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); + auto * flashParameters = const_cast< FlashParameters * >(m_parameters->get< FlashParameters >()); + flashParameters->m_continuousParameters[FlashParameters::STABILITY_TOLERANCE] = 1.0e-5; + + m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::VAPOUR)); - + m_flash = std::make_unique< NegativeTwoPhaseFlashModel >( "FlashModel", componentProperties, *m_parameters, m_phaseTypes ); } @@ -126,10 +148,10 @@ m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); stackArray2d< real64, (numPhases-1)*numComps > kValues( numPhases-1, numComps ); LvArray::forValuesInSlice( kValues.toSlice(), []( real64 & v ){ v = 0.0; } ); - StackArray< real64, 3, numPhases, multifluid::LAYOUT_PHASE > phaseFractionData( 1, 1, numPhases ); - StackArray< real64, 4, numPhases *numDofs, multifluid::LAYOUT_PHASE_DC > dPhaseFractionData( 1, 1, numPhases, numDofs ); - StackArray< real64, 4, numPhases *numComps, multifluid::LAYOUT_PHASE_COMP > phaseComponentFractionData( 1, 1, numPhases, numComps ); - StackArray< real64, 5, numPhases *numComps *numDofs, multifluid::LAYOUT_PHASE_COMP_DC > dPhaseComponentFractionData( 1, 1, numPhases, numComps, numDofs ); + CompProp phaseFractionData( 1, 1, numPhases ); + PhaseProp dPhaseFractionData( 1, 1, numPhases, numDofs ); + PhaseProp phaseComponentFractionData( 1, 1, numPhases, numComps ); + PhaseComp dPhaseComponentFractionData( 1, 1, numPhases, numComps, numDofs ); auto phaseFraction = phaseFractionData[0][0]; auto dPhaseFraction = dPhaseFractionData[0][0]; @@ -172,10 +194,10 @@ m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); stackArray2d< real64, (numPhases-1)*numComps > kValues( numPhases-1, numComps ); LvArray::forValuesInSlice( kValues.toSlice(), []( real64 & v ){ v = 0.0; } ); - StackArray< real64, 3, numPhases, multifluid::LAYOUT_PHASE > phaseFractionData( 1, 1, numPhases ); - StackArray< real64, 4, numPhases *numDofs, multifluid::LAYOUT_PHASE_DC > dPhaseFractionData( 1, 1, numPhases, numDofs ); - StackArray< real64, 4, numPhases *numComps, multifluid::LAYOUT_PHASE_COMP > phaseComponentFractionData( 1, 1, numPhases, numComps ); - StackArray< real64, 5, numPhases *numComps *numDofs, multifluid::LAYOUT_PHASE_COMP_DC > dPhaseComponentFractionData( 1, 1, numPhases, numComps, numDofs ); + CompProp phaseFractionData( 1, 1, numPhases ); + PhaseProp dPhaseFractionData( 1, 1, numPhases, numDofs ); + PhaseProp phaseComponentFractionData( 1, 1, numPhases, numComps ); + PhaseComp dPhaseComponentFractionData( 1, 1, numPhases, numComps, numDofs ); auto phaseFraction = phaseFractionData[0][0]; auto dPhaseFraction = dPhaseFractionData[0][0]; @@ -194,25 +216,9 @@ m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); PhasePropSlice( phaseFraction, dPhaseFraction ), PhaseCompSlice( phaseComponentFraction, dPhaseComponentFraction ) ); - -/** - - Z: { 0.10900000, 0.00300000, 0.23470000, 0.11460000, 0.08790000, 0.04560000, 0.02090000, 0.01510000, 0.36920000 } - X: { 0.15807941, 0.00337666, 0.07159711, 0.02384273, 0.10085780, 0.06146075, 0.02939718, 0.00974393, 0.54164443 } - Y: { 0.00396181, 0.00219389, 0.58376764, 0.30883583, 0.06016813, 0.01165533, 0.00271459, 0.02656289, 0.00013988 } - - */ - std::cout << " Z: " << composition.toSliceConst() << std::endl; - std::cout << " X: " << phaseComponentFraction[0] << std::endl; - std::cout << " Y: " << phaseComponentFraction[1] << std::endl; - std::cout << " V: " << phaseFraction.toSliceConst() << std::endl; - std::cout << std::scientific; - std::cout << "DV: " << dPhaseFraction[0] << std::endl; - std::cout << "DV: " << dPhaseFraction[1] << std::endl; -/** // Combine derivatives into a single output - auto const concatDerivatives = []( integer const kc, auto & derivs, auto const & phaseFractionDerivs, auto const & - phaseComponentFractionDerivs ){ + auto const concatDerivatives = []( integer const kc, auto & derivs, auto const & phaseFractionDerivs, + auto const & phaseComponentFractionDerivs ){ integer j = 0; for( integer ip = 0; ip < numPhases; ++ip ) { @@ -225,18 +231,18 @@ m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); }; auto const evaluateFlash = [&]( real64 const p, real64 const t, auto const & zmf, auto & values ){ - StackArray< real64, 3, numPhases, multifluid::LAYOUT_PHASE > displacedPhaseFractionData( 1, 1, numPhases ); - StackArray< real64, 4, numPhases *numDofs, multifluid::LAYOUT_PHASE_DC > displacedPhaseFractionDerivsData( 1, 1, numPhases, numDofs ); - StackArray< real64, 4, numPhases *numComps, multifluid::LAYOUT_PHASE_COMP > displacedPhaseComponentFractionData( 1, 1, numPhases, - numComps ); - StackArray< real64, 5, numPhases *numComps *numDofs, multifluid::LAYOUT_PHASE_COMP_DC > displacedPhaseComponentFractionDerivsData( 1, - 1, numPhases, numComps, numDofs ); + CompProp displacedPhaseFractionData( 1, 1, numPhases ); + PhaseProp displacedPhaseFractionDerivsData( 1, 1, numPhases, numDofs ); + PhaseProp displacedPhaseComponentFractionData( 1, 1, numPhases, numComps ); + PhaseComp displacedPhaseComponentFractionDerivsData( 1, 1, numPhases, numComps, numDofs ); auto displacedPhaseFraction = displacedPhaseFractionData[0][0]; auto displacedPhaseFractionDerivs = displacedPhaseFractionDerivsData[0][0]; auto displacedPhaseComponentFraction = displacedPhaseComponentFractionData[0][0]; auto displacedPhaseComponentFractionDerivs = displacedPhaseComponentFractionDerivsData[0][0]; + LvArray::forValuesInSlice( kValues.toSlice(), []( real64 & v ){ v = 0.0; } ); + flashKernelWrapper.compute( componentProperties, p, t, @@ -267,15 +273,14 @@ m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); // -- Temperature derivative concatDerivatives( Deriv::dT, derivatives, dPhaseFraction, dPhaseComponentFraction ); - real64 const dT = 1.0e-6 * temperature; + real64 const dT = 1.0e-4 * temperature; geos::testing::internal::testNumericalDerivative< numValues >( temperature, dT, derivatives, [&]( real64 const t, auto & values ) { evaluateFlash( pressure, t, composition.toSliceConst(), values ); } ); - // -- Composition derivatives derivative - real64 const dz = 1.0e-7; + real64 const dz = 1.0e-6; for( integer const ic : FluidData< numComps >::testComponents ) { real64 sumZ = 0.0; @@ -301,7 +306,6 @@ m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); evaluateFlash( pressure, temperature, zmf.toSliceConst(), values ); } ); } - */ } protected: @@ -312,7 +316,8 @@ m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); }; //using NegativeTwoPhaseFlashModel3 = NegativeTwoPhaseFlashModelTestFixture< 3 >; -using NegativeTwoPhaseFlashModel9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; +//using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; +using SoreideWhitson4 = NegativeTwoPhaseFlashModelTestFixture< 4, EquationOfStateType::SoreideWhitson >; //TEST_P( NegativeTwoPhaseFlashModel3, testFlash ) //{ @@ -327,7 +332,11 @@ using NegativeTwoPhaseFlashModel9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; //{ // testFlash( GetParam() ); //} -TEST_P( NegativeTwoPhaseFlashModel9, testFlashDerivatives ) +//TEST_P( PengRobinson9, testFlashDerivatives ) +//{ +// testFlashDerivatives( GetParam() ); +//} +TEST_P( SoreideWhitson4, testFlashDerivatives ) { testFlashDerivatives( GetParam() ); } @@ -336,36 +345,27 @@ TEST_P( NegativeTwoPhaseFlashModel9, testFlashDerivatives ) // Data //------------------------------------------------------------------------------- /* UNCRUSTIFY-OFF */ - +/** INSTANTIATE_TEST_SUITE_P( - NegativeTwoPhaseFlashModel, NegativeTwoPhaseFlashModel9, + NegativeTwoPhaseFlashModel, PengRobinson9, ::testing::ValuesIn>({ - {1.0000e+07, 293.15, {0.10900000, 0.00300000, 0.23470000, 0.11460000, 0.08790000, 0.04560000, 0.02090000, 0.01510000, 0.36920000}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}}, - {1.5000e+07, 293.15, {0.13701652, 0.00320982, 0.10906376, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883838}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}}, - {1.0000e+07, 293.15, {0.13701652, 0.00320982, 0.10906376, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883838}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}}, - {0.9999e+07, 293.15, {0.13701652, 0.00320982, 0.10906376, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883838}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} + //{1.0000e+07, 293.15, {0.10900000, 0.00300000, 0.23470000, 0.11460000, 0.08790000, 0.04560000, 0.02090000, 0.01510000, 0.36920000}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} + //{1.5000e+07, 293.15, {0.13701652, 0.00320982, 0.10906376, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883838}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}}, + //{1.0000e+07, 293.15, {0.13701652, 0.00320982, 0.10906370, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883844}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} + {1.0000e+07, 293.15, {0.13701652, 0.00320982, 0.10906370, 0.00000000, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.55543249}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} + //{1.0001e+07, 293.15, {0.13701652, 0.00320982, 0.10906376, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883838}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} //FlashData<9>{1.0000e+07, 293.15, {0.00396181, 0.00219389, 0.58376764, 0.30883583, 0.06016813, 0.01165533, 0.00271459, 0.02656289, 0.00013988}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} + }) +); +*/ - /**, - FlashData<9>{1.0e+06, 293.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.198828, 0.792172, 0.009000, {0.000000, 0.011551, 0.850986}, {0.000000, 0.672081, 0.000000}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+07, 293.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.307007, 0.683993, 0.009000, {0.000000, 0.111647, 0.551128}, {0.000000, 0.731621, 0.000000}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+08, 293.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.991000, 0.000000, 0.009000, {0.000000, 0.539556, 0.170737}, {0.000000, 0.539556, 0.170737}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+06, 313.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.190493, 0.800507, 0.009000, {0.000000, 0.010985, 0.888223}, {0.000000, 0.665337, 0.000000}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+07, 313.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.288620, 0.702380, 0.009000, {0.000000, 0.106713, 0.586237}, {0.000000, 0.717418, 0.000001}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+08, 313.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.991000, 0.000000, 0.009000, {0.000000, 0.539556, 0.170737}, {0.000000, 0.539556, 0.170737}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+06, 353.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.181787, 0.809213, 0.009000, {0.000000, 0.010453, 0.930750}, {0.000000, 0.658417, 0.000003}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+07, 353.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.261660, 0.729340, 0.009000, {0.000000, 0.101277, 0.646622}, {0.000000, 0.696794, 0.000007}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+08, 353.15, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 0.947424, 0.043576, 0.009000, {0.000000, 0.529993, 0.178339}, {0.000000, 0.747468, 0.005438}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+06, 293.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.120388, 0.479612, 0.400000, {0.000000, 0.011551, 0.850996}, {0.000000, 0.672084, 0.000000}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+08, 293.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.600000, 0.000000, 0.400000, {0.000000, 0.539550, 0.170750}, {0.000000, 0.539550, 0.170750}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+06, 313.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.115342, 0.484658, 0.400000, {0.000000, 0.010985, 0.888229}, {0.000000, 0.665341, 0.000000}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+07, 313.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.174755, 0.425245, 0.400000, {0.000000, 0.106714, 0.586247}, {0.000000, 0.717425, 0.000001}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+08, 313.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.600000, 0.000000, 0.400000, {0.000000, 0.539550, 0.170750}, {0.000000, 0.539550, 0.170750}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+06, 353.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.110071, 0.489929, 0.400000, {0.000000, 0.010453, 0.930753}, {0.000000, 0.658421, 0.000003}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+07, 353.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.158432, 0.441568, 0.400000, {0.000000, 0.101278, 0.646630}, {0.000000, 0.696800, 0.000007}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+08, 353.15, {0.400000, 0.001820, 0.323730, 0.069380, 0.053220, 0.027610, 0.012650, 0.009140, 0.102450}, 0.573644, 0.026356, 0.400000, {0.000000, 0.529997, 0.178345}, {0.000000, 0.747479, 0.005437}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+06, 313.15, {1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000}, 0.000000, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}, {1.000000, 0.000000, 0.000000}}, - FlashData<9>{1.0e+08, 353.15, {1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000}, 0.000000, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}, {1.000000, 0.000000, 0.000000}}*/ +INSTANTIATE_TEST_SUITE_P( + NegativeTwoPhaseFlashModel, SoreideWhitson4, + ::testing::ValuesIn>({ + //{1.0e+07, 293.15, {0.000000, 0.000000, 0.000000, 1.000000}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + //{1.0e+07, 293.15, {0.000005, 0.000005, 0.000005, 0.999985}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + //{1.0e+07, 293.15, {0.000000, 1.000000, 0.000000, 0.000000}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + {1.0e+07, 293.15, {0.000005, 0.999985, 0.000005, 0.000005}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} }) ); diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp index 45b5864ef4a..d5bbbbda39e 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp @@ -68,6 +68,7 @@ class StabilityTestTest2CompFixture : public ::testing::TestWithParam< Stabilit real64 tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; stackArray1d< real64, numComps > kValues( numComps ); + stackArray1d< real64, numComps > incipientComposition( numComps ); KValueInitialization::computeWilsonGasLiquidKvalue( numComps, pressure, @@ -85,10 +86,11 @@ class StabilityTestTest2CompFixture : public ::testing::TestWithParam< Stabilit componentProperties, EOS_TYPE, flashData, + kValues.toSliceConst(), flashParameters->m_continuousParameters, flashParameters->m_discreteParameters, tangentPlaneDistance, - kValues.toSlice() ); + incipientComposition.toSlice() ); // Expect this to succeed ASSERT_EQ( stabilityStatus, true ); diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp index 88ca5aba8c6..2eeb0582ed7 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp @@ -68,6 +68,7 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat real64 tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; stackArray1d< real64, numComps > kValues( numComps ); + stackArray1d< real64, numComps > incipientComposition( numComps ); KValueInitialization::computeWilsonGasLiquidKvalue( numComps, pressure, @@ -85,10 +86,11 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat componentProperties, EOS_TYPE, flashData, + kValues.toSliceConst(), flashParameters->m_continuousParameters, flashParameters->m_discreteParameters, tangentPlaneDistance, - kValues.toSlice() ); + incipientComposition.toSlice() ); // Expect this to succeed ASSERT_EQ( stabilityStatus, true ); @@ -112,6 +114,7 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat real64 tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; stackArray2d< real64, numComps > kValues( 1, numComps ); + stackArray1d< real64, numComps > incipientComposition( numComps ); KValueInitialization::computeWilsonGasLiquidKvalue( numComps, pressure, @@ -129,10 +132,11 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat componentProperties, EOS_TYPE, flashData, + kValues[0].toSliceConst(), flashParameters->m_continuousParameters, flashParameters->m_discreteParameters, tangentPlaneDistance, - kValues[0] ); + incipientComposition.toSlice() ); // Now perform the nagative flash real64 vapourFraction = -1.0; From fb5de4a5941799cdbc278ff1ccfab0957405ec32 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Tue, 22 Jul 2025 11:18:14 -0500 Subject: [PATCH 08/28] Nagative flash dervatives --- .../functions/NegativeTwoPhaseFlash_impl.hpp | 156 ++++++++++++------ .../compositional/functions/StabilityTest.hpp | 27 +-- .../models/NegativeTwoPhaseFlashModel.hpp | 9 +- .../unitTests/TestFluidUtilities.hpp | 15 +- .../testNegativeTwoPhaseFlashModel.cpp | 109 +++++++----- src/coreComponents/schema/schema.xsd | 40 +++++ src/coreComponents/schema/schema.xsd.other | 8 - 7 files changed, 228 insertions(+), 136 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index be98d2ff301..d4df0139961 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -178,10 +178,12 @@ void NegativeTwoPhaseFlash::computeDerivatives( else { // Calculate the liquid and vapour fugacities and derivatives - StackArray< real64, 1, maxNumComps > logLiquidFugacity( numComps ); - StackArray< real64, 1, maxNumComps > logVapourFugacity( numComps ); - StackArray< real64, 2, maxNumComps * maxNumDofs, MatrixLayout::ROW_MAJOR_PERM > logLiquidFugacityDerivs( numComps, numDofs ); - StackArray< real64, 2, maxNumComps * maxNumDofs, MatrixLayout::ROW_MAJOR_PERM > logVapourFugacityDerivs( numComps, numDofs ); + StackArray< real64, 2, 2*maxNumComps > logFugacity( 2, numComps ); + StackArray< real64, 3, 2*maxNumComps * maxNumDofs > logFugacityDerivs( 2, numComps, numDofs ); + arraySlice1d< real64 > const logLiquidFugacity = logFugacity[0]; + arraySlice1d< real64 > const logVapourFugacity = logFugacity[1]; + arraySlice2d< real64 > const logLiquidFugacityDerivs = logFugacityDerivs[0]; + arraySlice2d< real64 > const logVapourFugacityDerivs = logFugacityDerivs[1]; FugacityCalculator::computeLogFugacityDerivatives( numComps, pressure, @@ -190,8 +192,8 @@ void NegativeTwoPhaseFlash::computeDerivatives( componentProperties, flashData.liquidEos, flashData, - logLiquidFugacity.toSlice(), - logLiquidFugacityDerivs.toSlice() ); + logLiquidFugacity, + logLiquidFugacityDerivs ); FugacityCalculator::computeLogFugacityDerivatives( numComps, pressure, temperature, @@ -199,83 +201,127 @@ void NegativeTwoPhaseFlash::computeDerivatives( componentProperties, flashData.vapourEos, flashData, - logVapourFugacity.toSlice(), - logVapourFugacityDerivs.toSlice() ); + logVapourFugacity, + logVapourFugacityDerivs ); - constexpr integer maxNumVals = 2*MultiFluidConstants::MAX_NUM_COMPONENTS+1; - integer const numVals = 2*numComps; - StackArray< real64, 2, maxNumVals * maxNumVals, MatrixLayout::COL_MAJOR_PERM > A( numVals + 1, numVals + 1 ); - StackArray< real64, 2, maxNumVals * maxNumVals, MatrixLayout::COL_MAJOR_PERM > X( numVals + 1, numVals + 1 ); + constexpr integer maxNumVals = MultiFluidConstants::MAX_NUM_COMPONENTS+1; + StackArray< real64, 2, maxNumVals * maxNumVals, MatrixLayout::COL_MAJOR_PERM > A( numComps + 1, numComps + 1 ); + StackArray< real64, 2, maxNumVals * maxNumDofs, MatrixLayout::COL_MAJOR_PERM > X( numComps + 1, numDofs ); - LvArray::forValuesInSlice( A.toSlice(), setZero ); - LvArray::forValuesInSlice( X.toSlice(), setZero ); + arraySlice1d< real64 > const & liquidFugacity = logLiquidFugacity; + arraySlice1d< real64 > const & vapourFugacity = logVapourFugacity; + for( integer i = 0; i < numComps; ++i ) + { + liquidFugacity[i] = LvArray::math::exp( logLiquidFugacity[i] ); + vapourFugacity[i] = LvArray::math::exp( logVapourFugacity[i] ); + } - for( integer ic = 0; ic < numComps; ++ic ) + // Precalculate some factors + real64 const V = vapourFraction; + real64 const factor1 = V / (1.0 - V); + real64 const factor2 = 1.0 / (1.0 - V); + + for( integer i = 0; i < numComps; ++i ) { - integer const xi = ic; - integer const yi = ic + numComps; - integer const vi = numVals; - - integer e = ic; - A( e, xi ) = 1.0 - vapourFraction; - A( e, yi ) = vapourFraction; - A( e, vi ) = vapourComposition[ic] - liquidComposition[ic]; - - e = ic + numComps; - real64 const phiL = exp( logLiquidFugacity( ic ) ); - real64 const phiV = exp( logVapourFugacity( ic ) ); - for( integer jc = 0; jc < numComps; ++jc ) + real64 const phi_L_i = liquidFugacity[i]; + real64 const phi_V_i = vapourFugacity[i]; + + real64 const xi = liquidComposition[i]; + real64 const yi = vapourComposition[i]; + + real64 col_N = 0.0; + for( integer j = 0; j < numComps; ++j ) { - integer const xj = jc; - integer const yj = jc + numComps; - real64 const dPhiLdx = logLiquidFugacityDerivs( ic, Deriv::dC+jc ); - real64 const dPhiVdy = logVapourFugacityDerivs( ic, Deriv::dC+jc ); - A( e, xj ) = liquidComposition[ic] * phiL * dPhiLdx; - A( e, yj ) = -vapourComposition[ic] * phiV * dPhiVdy; + real64 const xj = liquidComposition[j]; + real64 const yj = vapourComposition[j]; + + real64 const c1_ij = xi * phi_L_i * logLiquidFugacityDerivs( i, Deriv::dC+j ); + real64 const c2_ij = -yi * phi_V_i * logVapourFugacityDerivs( i, Deriv::dC+j ); + + A( i, j ) = c2_ij - factor1 * c1_ij; + + col_N += c1_ij * (yj - xj); } - A( e, xi ) += phiL; - A( e, yi ) -= phiV; - e = numVals; - A( e, xi ) = -1.0; - A( e, yi ) = 1.0; + A( i, i ) -= (phi_V_i + factor1 * phi_L_i); + + col_N += phi_L_i * (yi - xi); + + A( i, numComps ) = -factor2 * col_N; + A( numComps, i ) = factor2; } + A( numComps, numComps ) = 0.0; // Pressure and temperature derivatives for( integer ic = 0; ic < numComps; ++ic ) { - real64 const phiL = -liquidComposition[ic] * exp( logLiquidFugacity( ic ) ); - real64 const phiV = vapourComposition[ic] * exp( logVapourFugacity( ic ) ); - X( ic + numComps, Deriv::dP ) = phiL * logLiquidFugacityDerivs( ic, Deriv::dP ) + - phiV * logVapourFugacityDerivs( ic, Deriv::dP ); - X( ic + numComps, Deriv::dT ) = phiL * logLiquidFugacityDerivs( ic, Deriv::dT ) + - phiV * logVapourFugacityDerivs( ic, Deriv::dT ); + real64 const phiL = -liquidComposition[ic] * liquidFugacity[ic]; + real64 const phiV = vapourComposition[ic] * vapourFugacity[ ic ]; + X( ic, Deriv::dP ) = phiL * logLiquidFugacityDerivs( ic, Deriv::dP ) + + phiV * logVapourFugacityDerivs( ic, Deriv::dP ); + X( ic, Deriv::dT ) = phiL * logLiquidFugacityDerivs( ic, Deriv::dT ) + + phiV * logVapourFugacityDerivs( ic, Deriv::dT ); } + X( numComps, Deriv::dP ) = 0.0; + X( numComps, Deriv::dT ) = 0.0; // Composition derivatives - for( integer kc = 0; kc < numComps; ++kc ) + for( integer k = 0; k < numComps; ++k ) { - integer const idof = Deriv::dC + kc; + integer const idof = Deriv::dC + k; - for( integer ic = 0; ic < numComps; ++ic ) + for( integer i = 0; i < numComps; ++i ) { - X( ic, idof ) = -composition[ic]; + real64 const phi_L_i = liquidFugacity[i]; + real64 const xi = liquidComposition[i]; + real64 const zi = composition[i]; + + real64 row_i = 0.0; + for( integer j = 0; j < numComps; ++j ) + { + row_i -= xi * phi_L_i * logLiquidFugacityDerivs( i, Deriv::dC + j ) * composition[j]; + } + row_i += xi * phi_L_i * logLiquidFugacityDerivs( i, Deriv::dC + k ); + row_i -= phi_L_i * zi; + + X( i, idof ) = -factor2 * row_i; } - X( kc, idof ) += 1.0; + X( k, idof ) -= factor2 * liquidFugacity[k]; + X( numComps, idof ) = 0.0; } // Solve linear system solveLinearSystem( A.toSlice(), X.toSlice() ); // Fill in the derivatives - for( integer idof = 0; idof < numDofs; ++idof ) + for( integer i = 0; i < numComps; ++i ) { - for( integer ic = 0; ic < numComps; ++ic ) + real64 const xi = liquidComposition[i]; + real64 const yi = vapourComposition[i]; + real64 const zi = composition[i]; + + for( integer const idof : {Deriv::dP, Deriv::dT} ) + { + real64 const dV = X( numComps, idof ); + real64 const dy = X( i, idof ); + real64 const dx = factor2*((xi - yi)*dV - V*dy); + + vapourFractionDerivs( idof ) = dV; + vapourCompositionDerivs( i, idof ) = dy; + liquidCompositionDerivs( i, idof ) = dx; + } + for( integer j = 0; j < numComps; ++j ) { - liquidCompositionDerivs( ic, idof ) = X( ic, idof ); - vapourCompositionDerivs( ic, idof ) = X( ic + numComps, idof ); + integer const idof = Deriv::dC+j; + real64 const dV = X( numComps, idof ); + real64 const dy = X( i, idof ); + real64 const dx = factor2*(-zi + (xi - yi)*dV - V*dy); + + vapourFractionDerivs( idof ) = dV; + vapourCompositionDerivs( i, idof ) = dy; + liquidCompositionDerivs( i, idof ) = dx; } - vapourFractionDerivs( idof ) = X( numVals, idof ); + liquidCompositionDerivs( i, Deriv::dC+i ) += factor2; } } } diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp index ece509ab512..8a59b16c674 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp @@ -122,13 +122,24 @@ struct StabilityTest // Measure of distance to trivial solution real64 maxDistanceToTrivialSolution = 0.0; - for( real64 const alpha : { 1.0, -1.0 } ) + for( real64 const alpha : { 1.0, -1.0, 0.0 } ) { // Initialise next sample - for( integer const ic : presentComponents ) + if( LvArray::math::abs( alpha ) < MultiFluidConstants::epsilon ) + { + for( integer const ic : presentComponents ) + { + logTrialComposition[ic] = 0.0; + normalizedComposition[ic] = 1.0; + } + } + else { - logTrialComposition[ic] = LvArray::math::log( composition[ic] ) + alpha*LvArray::math::log( kValues[ic] ); - normalizedComposition[ic] = LvArray::math::exp( logTrialComposition[ic] ); + for( integer const ic : presentComponents ) + { + logTrialComposition[ic] = LvArray::math::log( composition[ic] ) + alpha*LvArray::math::log( kValues[ic] ); + normalizedComposition[ic] = LvArray::math::exp( logTrialComposition[ic] ); + } } // Start iterations for this sample bool converged = false; @@ -159,14 +170,6 @@ struct StabilityTest { tangentPlaneDistance = tpd; } - std::cout - << std::fixed << std::setprecision( 1 ) << std::setw( 4 ) << alpha << " " - << std::setw( 3 ) << iterationCount << " " - << std::fixed << std::setprecision( 6 ) << std::setw( 4 ) << normalizedComposition << " " - << std::scientific << std::setprecision( 6 ) << logFugacity << " " - << std::scientific << std::setprecision( 6 ) << std::setw( 13 ) << tpd << " " - << std::scientific << std::setprecision( 6 ) << std::setw( 13 ) << error << " " - << "\n"; // Check stationarity if( error < stabilityTolerance ) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp index 5dd19b861f3..43b8f1a22b8 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp @@ -80,7 +80,8 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate integer const numDofs = 2 + m_numComponents; - stackArray1d< real64, maxNumComps > incipientComposition( m_numComponents ); + StackArray< real64, 2, maxNumComps > compositions( 1, m_numComponents ); + arraySlice1d< real64 > incipientComposition = compositions[0]; // Check if k-Values need to be initialised auto kVapourLiquid = kValues[0]; @@ -125,7 +126,7 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate m_continuousFlashParameters.toSliceConst(), m_discreteFlashParameters.toSliceConst(), tangentPlaneDistance, - incipientComposition.toSlice() ); + incipientComposition ); } // If the stability test failed to converge to a stationary point then we will assume the mixture is unstable @@ -188,10 +189,6 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate sampleIndex = m_vapourIndex; incipientIndex = m_liquidIndex; } - std::cout << "LI " << sampleTemperature << " " << incipientTemperature << " " << incipientTemperature-sampleTemperature << " " - << "{" << sampleIndex << ", " << incipientIndex << "} " - << "{" << m_liquidIndex << ", " << m_vapourIndex << "} " - << "\n"; phaseFraction.value[m_vapourIndex] = (sampleIndex == m_vapourIndex) ? 1.0 : 0.0; diff --git a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp index f5b2a2761a5..80aae8c1932 100644 --- a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp +++ b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp @@ -108,20 +108,9 @@ void testNumericalDerivative( real64 const x, selectedDerivative = deriv; } } - ((void)absTolerance); - ((void)relTolerance); - //checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, - // GEOS_FMT( "Numerical derivative for component {}", i ) ); - std::cout << std::setw( 2 ) << i << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 13 ) << derivatives[i] << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 13 ) << selectedDerivative << " | " - << std::scientific << std::setprecision( 5 ) << std::setw( 13 ) << derivatives[i]-selectedDerivative << " | " - << std::scientific << std::setprecision( 5 ) << std::setw( 13 ) << leftValues[i] << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 13 ) << centreValues[i] << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 13 ) << rightValues[i] << " " - << "\n"; + checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, + GEOS_FMT( "Numerical derivative for component {}", i ) ); } - std::cout << "-----------------------------------------------------------------------\n"; } /** diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp index de3e690fffe..d3f6980d6bb 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp @@ -49,13 +49,13 @@ template< integer NC > struct FluidData {}; template<> -struct FluidData< 3 > +struct FluidData< 2 > { - static constexpr integer testComponents[numTestComps] = {0, 1, 2}; - static std::unique_ptr< TestFluid< 3 > > createFluid() + static constexpr integer testComponents[numTestComps] = {0, 1, 1}; + static std::unique_ptr< TestFluid< 2 > > createFluid() { - auto fluid = TestFluid< 3 >::create( {Fluid::CH4, Fluid::C10H22, Fluid::H2O} ); - const std::array< real64 const, 3 > bics = { 0.25, 0.0, 0.0 }; + auto fluid = TestFluid< 2 >::create( {Fluid::CH4, Fluid::C5H12} ); + const std::array< real64 const, 2 > bics = { 0.5 }; fluid->setBinaryCoefficients( bics ); return fluid; } @@ -124,9 +124,6 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< criticalVolume->m_componentCriticalVolume.resize( numComps ); TestFluid< NC >::populateArray( criticalVolume->m_componentCriticalVolume, this->m_fluid->criticalVolume ); - auto * flashParameters = const_cast< FlashParameters * >(m_parameters->get< FlashParameters >()); - flashParameters->m_continuousParameters[FlashParameters::STABILITY_TOLERANCE] = 1.0e-5; - m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::VAPOUR)); @@ -169,6 +166,9 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< PhasePropSlice( phaseFraction, dPhaseFraction ), PhaseCompSlice( phaseComponentFraction, dPhaseComponentFraction ) ); + ((void)expectedPhaseFraction); + ((void)expectedPhaseComponentFraction); + return; for( integer ip = 0; ip < numPhases; ip++ ) { checkRelativeError( phaseFraction[ip], expectedPhaseFraction[ip], relTol, absTol ); @@ -182,7 +182,6 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< void testFlashDerivatives( FlashData< NC > const & data ) { - std::cout << std::fixed << std::setprecision( 8 ); // Number of output values from each flash calculation constexpr integer numValues = numPhases * (1 + numComps); @@ -208,6 +207,7 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< auto componentProperties = m_fluid->createKernelWrapper(); auto flashKernelWrapper = m_flash->createKernelWrapper(); + flashKernelWrapper.compute( componentProperties, pressure, temperature, @@ -218,19 +218,20 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< // Combine derivatives into a single output auto const concatDerivatives = []( integer const kc, auto & derivs, auto const & phaseFractionDerivs, - auto const & phaseComponentFractionDerivs ){ + auto const & phaseComponentFractionDerivs, + real64 const scale = 1.0 ){ integer j = 0; for( integer ip = 0; ip < numPhases; ++ip ) { - derivs[j++] = phaseFractionDerivs( ip, kc ); + derivs[j++] = scale * phaseFractionDerivs( ip, kc ); for( integer ic = 0; ic < numComps; ++ic ) { - derivs[j++] = phaseComponentFractionDerivs( ip, ic, kc ); + derivs[j++] = scale * phaseComponentFractionDerivs( ip, ic, kc ); } } }; - auto const evaluateFlash = [&]( real64 const p, real64 const t, auto const & zmf, auto & values ){ + auto const evaluateFlash = [&]( real64 const p, real64 const t, auto const & zmf, auto & values, real64 const scale = 1.0 ){ CompProp displacedPhaseFractionData( 1, 1, numPhases ); PhaseProp displacedPhaseFractionDerivsData( 1, 1, numPhases, numDofs ); PhaseProp displacedPhaseComponentFractionData( 1, 1, numPhases, numComps ); @@ -253,22 +254,23 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< integer j = 0; for( integer ip = 0; ip < numPhases; ++ip ) { - values[j++] = displacedPhaseFraction[ip]; + values[j++] = scale * displacedPhaseFraction[ip]; for( integer ic = 0; ic < numComps; ++ic ) { - values[j++] = displacedPhaseComponentFraction( ip, ic ); + values[j++] = scale * displacedPhaseComponentFraction( ip, ic ); } } }; // Test against numerically calculated values // --- Pressure derivatives --- - concatDerivatives( Deriv::dP, derivatives, dPhaseFraction, dPhaseComponentFraction ); + real64 constexpr pressureScale = 1.0e6; + concatDerivatives( Deriv::dP, derivatives, dPhaseFraction, dPhaseComponentFraction, pressureScale ); real64 const dp = 1.0e-4 * pressure; geos::testing::internal::testNumericalDerivative< numValues >( pressure, dp, derivatives, [&]( real64 const p, auto & values ) { - evaluateFlash( p, temperature, composition.toSliceConst(), values ); + evaluateFlash( p, temperature, composition.toSliceConst(), values, pressureScale ); } ); // -- Temperature derivative @@ -279,6 +281,7 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< [&]( real64 const t, auto & values ) { evaluateFlash( pressure, t, composition.toSliceConst(), values ); } ); + // -- Composition derivatives derivative real64 const dz = 1.0e-6; for( integer const ic : FluidData< numComps >::testComponents ) @@ -315,49 +318,56 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< array1d< integer > m_phaseTypes{}; }; -//using NegativeTwoPhaseFlashModel3 = NegativeTwoPhaseFlashModelTestFixture< 3 >; -//using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; +using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; +using SoaveRedlichKwong2 = NegativeTwoPhaseFlashModelTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; using SoreideWhitson4 = NegativeTwoPhaseFlashModelTestFixture< 4, EquationOfStateType::SoreideWhitson >; -//TEST_P( NegativeTwoPhaseFlashModel3, testFlash ) -//{ -// testFlash( GetParam() ); -//} -//TEST_P( NegativeTwoPhaseFlashModel3, testFlashDerivatives ) -//{ -// testFlashDerivatives( GetParam() ); -//} - -//TEST_P( NegativeTwoPhaseFlashModel9, testFlash ) -//{ -// testFlash( GetParam() ); -//} -//TEST_P( PengRobinson9, testFlashDerivatives ) -//{ -// testFlashDerivatives( GetParam() ); -//} +TEST_P( PengRobinson9, testFlashDerivatives ) +{ + testFlash( GetParam() ); +} +TEST_P( SoaveRedlichKwong2, testFlashDerivatives ) +{ + testFlash( GetParam() ); +} TEST_P( SoreideWhitson4, testFlashDerivatives ) { - testFlashDerivatives( GetParam() ); + testFlash( GetParam() ); } +/** + TEST_P( PengRobinson9, testFlashDerivatives ) + { + testFlashDerivatives( GetParam() ); + } + TEST_P( SoaveRedlichKwong2, testFlashDerivatives ) + { + testFlashDerivatives( GetParam() ); + } + TEST_P( SoreideWhitson4, testFlashDerivatives ) + { + testFlashDerivatives( GetParam() ); + } + */ //------------------------------------------------------------------------------- // Data //------------------------------------------------------------------------------- /* UNCRUSTIFY-OFF */ -/** + INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, PengRobinson9, ::testing::ValuesIn>({ + //{1.0000e+07, 293.15, {0.005499, 0.002225, 0.698843, 0.218062, 0.059526, 0.012000, 0.002131, 0.000613, 0.001100}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} + //{1.0000e+07, 293.15, {0.005499, 0.002225, 0.698836, 0.218062, 0.059526, 0.012000, 0.002131, 0.000613, 0.001107}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} //{1.0000e+07, 293.15, {0.10900000, 0.00300000, 0.23470000, 0.11460000, 0.08790000, 0.04560000, 0.02090000, 0.01510000, 0.36920000}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} - //{1.5000e+07, 293.15, {0.13701652, 0.00320982, 0.10906376, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883838}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}}, + {1.0000e+07, 293.15, {0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} //{1.0000e+07, 293.15, {0.13701652, 0.00320982, 0.10906370, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883844}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} - {1.0000e+07, 293.15, {0.13701652, 0.00320982, 0.10906370, 0.00000000, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.55543249}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} + //{1.0000e+07, 293.15, {0.13701652, 0.00320982, 0.10906370, 0.00000000, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.55543249}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} //{1.0001e+07, 293.15, {0.13701652, 0.00320982, 0.10906376, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883838}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} //FlashData<9>{1.0000e+07, 293.15, {0.00396181, 0.00219389, 0.58376764, 0.30883583, 0.06016813, 0.01165533, 0.00271459, 0.02656289, 0.00013988}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} }) ); -*/ + INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoreideWhitson4, @@ -365,7 +375,22 @@ INSTANTIATE_TEST_SUITE_P( //{1.0e+07, 293.15, {0.000000, 0.000000, 0.000000, 1.000000}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} //{1.0e+07, 293.15, {0.000005, 0.000005, 0.000005, 0.999985}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} //{1.0e+07, 293.15, {0.000000, 1.000000, 0.000000, 0.000000}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} - {1.0e+07, 293.15, {0.000005, 0.999985, 0.000005, 0.000005}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + //{1.0e+07, 293.15, {0.000005, 0.999985, 0.000005, 0.000005}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + {1.0e+07, 293.15, {0.75, 0.05, 0.05, 0.15}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + }) +); + +INSTANTIATE_TEST_SUITE_P( + NegativeTwoPhaseFlashModel, SoaveRedlichKwong2, + ::testing::ValuesIn>({ + //{1.0e+07, 293.15, {0.000000, 0.000000, 0.000000, 1.000000}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + //{1.0e+07, 293.15, {0.000005, 0.000005, 0.000005, 0.999985}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + //{1.0e+07, 293.15, {0.000000, 1.000000, 0.000000, 0.000000}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + //{1.0e+07, 293.15, {0.000005, 0.999985, 0.000005, 0.000005}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + //{1.0e+07, 293.15, {0.75, 0.25}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + //{1.0e+07, 293.15, {0.077600, 0.922400}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + //{1.0e+07, 293.15, {0.1, 0.9}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + {1.0e+07, 293.15, {0.0, 1.0}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} }) ); diff --git a/src/coreComponents/schema/schema.xsd b/src/coreComponents/schema/schema.xsd index aca2fe256fa..d11f73f0a89 100644 --- a/src/coreComponents/schema/schema.xsd +++ b/src/coreComponents/schema/schema.xsd @@ -5850,8 +5850,18 @@ Information output from lower logLevels is added with the desired log level * SoaveRedlichKwong * SoreideWhitson--> + + + + + + + + + + + + + + + + + + + + @@ -5931,8 +5951,18 @@ Information output from lower logLevels is added with the desired log level * SoaveRedlichKwong * SoreideWhitson--> + + + + + + + + + + + + + + @@ -5973,6 +6007,12 @@ Information output from lower logLevels is added with the desired log level + + + + + + - - @@ -1938,8 +1936,6 @@ - - @@ -1990,8 +1986,6 @@ - - @@ -2042,8 +2036,6 @@ - - From 07353ba97de286c1480080140fafe802dfe68118 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Tue, 22 Jul 2025 19:42:29 -0500 Subject: [PATCH 09/28] Unit test --- .../functions/NegativeTwoPhaseFlash.hpp | 16 ++ .../functions/NegativeTwoPhaseFlash_impl.hpp | 255 ++++++++++-------- .../models/NegativeTwoPhaseFlashModel.hpp | 85 ++++-- .../testNegativeTwoPhaseFlashModel.cpp | 115 +++++--- 4 files changed, 298 insertions(+), 173 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp index a51cf561472..e18207cded2 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp @@ -134,6 +134,22 @@ struct NegativeTwoPhaseFlash arraySlice1d< real64 > const & logLiquidFugacity, arraySlice1d< real64 > const & logVapourFugacity, arraySlice1d< real64 > const & fugacityRatios ); + + template< integer USD1, integer USD2, integer USD3 > + GEOS_HOST_DEVICE + static void computeDerivatives( + integer const numComps, + arraySlice1d< real64 const > const & totalComposition, + real64 const & phase1Fraction, + arraySlice1d< real64 const, USD1 > const & phase1Composition, + arraySlice1d< real64 const, USD1 > const & phase2Composition, + arraySlice1d< real64 const > const & phase1Fugacity, + arraySlice1d< real64 const > const & phase2Fugacity, + arraySlice2d< real64 const > const & phase1LogFugacityDerivs, + arraySlice2d< real64 const > const & phase2LogFugacityDerivs, + arraySlice1d< real64, USD2 > const & phase1FractionDerivs, + arraySlice2d< real64, USD3 > const & phase1CompositionDerivs, + arraySlice2d< real64, USD3 > const & phase2CompositionDerivs ); }; } // namespace compositional diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index d4df0139961..6e3ff35613f 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -107,26 +107,6 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, } } - // Retrieve physical bounds from negative flash values - if( vapourPhaseMoleFraction < MultiFluidConstants::epsilon ) - { - vapourPhaseMoleFraction = 0.0; - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidComposition[ic] = composition[ic]; - vapourComposition[ic] = composition[ic]; - } - } - else if( 1.0 - vapourPhaseMoleFraction < MultiFluidConstants::epsilon ) - { - vapourPhaseMoleFraction = 1.0; - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidComposition[ic] = composition[ic]; - vapourComposition[ic] = composition[ic]; - } - } - return converged; } @@ -153,13 +133,12 @@ void NegativeTwoPhaseFlash::computeDerivatives( integer const numDofs = numComps + 2; - auto const setZero = []( real64 & val ) { val = 0.0; }; LvArray::forValuesInSlice( vapourFractionDerivs, setZero ); LvArray::forValuesInSlice( liquidCompositionDerivs, setZero ); LvArray::forValuesInSlice( vapourCompositionDerivs, setZero ); // Check if we are single or 2-phase - if( vapourFraction < MultiFluidConstants::epsilon ) + if( false && vapourFraction < MultiFluidConstants::epsilon ) { for( integer ic = 0; ic < numComps; ++ic ) { @@ -167,7 +146,7 @@ void NegativeTwoPhaseFlash::computeDerivatives( vapourCompositionDerivs( ic, Deriv::dC + ic ) = 1.0; } } - else if( 1.0 - vapourFraction < MultiFluidConstants::epsilon ) + else if( false && 1.0 - vapourFraction < MultiFluidConstants::epsilon ) { for( integer ic = 0; ic < numComps; ++ic ) { @@ -204,10 +183,6 @@ void NegativeTwoPhaseFlash::computeDerivatives( logVapourFugacity, logVapourFugacityDerivs ); - constexpr integer maxNumVals = MultiFluidConstants::MAX_NUM_COMPONENTS+1; - StackArray< real64, 2, maxNumVals * maxNumVals, MatrixLayout::COL_MAJOR_PERM > A( numComps + 1, numComps + 1 ); - StackArray< real64, 2, maxNumVals * maxNumDofs, MatrixLayout::COL_MAJOR_PERM > X( numComps + 1, numDofs ); - arraySlice1d< real64 > const & liquidFugacity = logLiquidFugacity; arraySlice1d< real64 > const & vapourFugacity = logVapourFugacity; for( integer i = 0; i < numComps; ++i ) @@ -216,113 +191,169 @@ void NegativeTwoPhaseFlash::computeDerivatives( vapourFugacity[i] = LvArray::math::exp( logVapourFugacity[i] ); } - // Precalculate some factors - real64 const V = vapourFraction; - real64 const factor1 = V / (1.0 - V); - real64 const factor2 = 1.0 / (1.0 - V); - - for( integer i = 0; i < numComps; ++i ) + if( vapourFraction < 0.5 ) + { + computeDerivatives( numComps, + composition, + vapourFraction, + vapourComposition, + liquidComposition, + vapourFugacity, + liquidFugacity, + logVapourFugacityDerivs, + logLiquidFugacityDerivs, + vapourFractionDerivs, + vapourCompositionDerivs, + liquidCompositionDerivs ); + } + else { - real64 const phi_L_i = liquidFugacity[i]; - real64 const phi_V_i = vapourFugacity[i]; + computeDerivatives( numComps, + composition, + 1.0 - vapourFraction, + liquidComposition, + vapourComposition, + liquidFugacity, + vapourFugacity, + logLiquidFugacityDerivs, + logVapourFugacityDerivs, + vapourFractionDerivs, + liquidCompositionDerivs, + vapourCompositionDerivs ); + LvArray::forValuesInSlice( vapourFractionDerivs, []( real64 & v ){ v *= -1.0; } ); + } + } +} - real64 const xi = liquidComposition[i]; - real64 const yi = vapourComposition[i]; +template< integer USD1, integer USD2, integer USD3 > +GEOS_HOST_DEVICE +void NegativeTwoPhaseFlash::computeDerivatives( + integer const numComps, + arraySlice1d< real64 const > const & totalComposition, + real64 const & phase1Fraction, + arraySlice1d< real64 const, USD1 > const & phase1Composition, + arraySlice1d< real64 const, USD1 > const & phase2Composition, + arraySlice1d< real64 const > const & phase1Fugacity, + arraySlice1d< real64 const > const & phase2Fugacity, + arraySlice2d< real64 const > const & phase1LogFugacityDerivs, + arraySlice2d< real64 const > const & phase2LogFugacityDerivs, + arraySlice1d< real64, USD2 > const & phase1FractionDerivs, + arraySlice2d< real64, USD3 > const & phase1CompositionDerivs, + arraySlice2d< real64, USD3 > const & phase2CompositionDerivs ) +{ + constexpr integer maxNumDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; + constexpr integer maxNumVals = MultiFluidConstants::MAX_NUM_COMPONENTS+1; - real64 col_N = 0.0; - for( integer j = 0; j < numComps; ++j ) - { - real64 const xj = liquidComposition[j]; - real64 const yj = vapourComposition[j]; + integer const numDofs = numComps + 2; - real64 const c1_ij = xi * phi_L_i * logLiquidFugacityDerivs( i, Deriv::dC+j ); - real64 const c2_ij = -yi * phi_V_i * logVapourFugacityDerivs( i, Deriv::dC+j ); + StackArray< real64, 2, maxNumVals * maxNumVals, MatrixLayout::COL_MAJOR_PERM > A( numComps + 1, numComps + 1 ); + StackArray< real64, 2, maxNumVals * maxNumDofs, MatrixLayout::COL_MAJOR_PERM > X( numComps + 1, numDofs ); - A( i, j ) = c2_ij - factor1 * c1_ij; + real64 const VL = phase1Fraction; + real64 const factor1 = VL / (1.0 - VL); + real64 const factor2 = 1.0 / (1.0 - VL); - col_N += c1_ij * (yj - xj); - } + for( integer i = 0; i < numComps; ++i ) + { + real64 const phi_2_i = phase2Fugacity[i]; + real64 const phi_1_i = phase1Fugacity[i]; - A( i, i ) -= (phi_V_i + factor1 * phi_L_i); + real64 const xi = phase2Composition[i]; + real64 const yi = phase1Composition[i]; - col_N += phi_L_i * (yi - xi); + real64 col_N = 0.0; + for( integer j = 0; j < numComps; ++j ) + { + real64 const xj = phase2Composition[j]; + real64 const yj = phase1Composition[j]; - A( i, numComps ) = -factor2 * col_N; - A( numComps, i ) = factor2; - } - A( numComps, numComps ) = 0.0; + real64 const c1_ij = xi * phi_2_i * phase2LogFugacityDerivs( i, Deriv::dC+j ); + real64 const c2_ij = -yi * phi_1_i * phase1LogFugacityDerivs( i, Deriv::dC+j ); - // Pressure and temperature derivatives - for( integer ic = 0; ic < numComps; ++ic ) - { - real64 const phiL = -liquidComposition[ic] * liquidFugacity[ic]; - real64 const phiV = vapourComposition[ic] * vapourFugacity[ ic ]; - X( ic, Deriv::dP ) = phiL * logLiquidFugacityDerivs( ic, Deriv::dP ) + - phiV * logVapourFugacityDerivs( ic, Deriv::dP ); - X( ic, Deriv::dT ) = phiL * logLiquidFugacityDerivs( ic, Deriv::dT ) + - phiV * logVapourFugacityDerivs( ic, Deriv::dT ); + A( i, j ) = c2_ij - factor1 * c1_ij; + + col_N += c1_ij * (yj - xj); } - X( numComps, Deriv::dP ) = 0.0; - X( numComps, Deriv::dT ) = 0.0; - // Composition derivatives - for( integer k = 0; k < numComps; ++k ) - { - integer const idof = Deriv::dC + k; + A( i, i ) -= (phi_1_i + factor1 * phi_2_i); - for( integer i = 0; i < numComps; ++i ) - { - real64 const phi_L_i = liquidFugacity[i]; - real64 const xi = liquidComposition[i]; - real64 const zi = composition[i]; - - real64 row_i = 0.0; - for( integer j = 0; j < numComps; ++j ) - { - row_i -= xi * phi_L_i * logLiquidFugacityDerivs( i, Deriv::dC + j ) * composition[j]; - } - row_i += xi * phi_L_i * logLiquidFugacityDerivs( i, Deriv::dC + k ); - row_i -= phi_L_i * zi; - - X( i, idof ) = -factor2 * row_i; - } - X( k, idof ) -= factor2 * liquidFugacity[k]; - X( numComps, idof ) = 0.0; - } + col_N += phi_2_i * (yi - xi); + + A( i, numComps ) = -factor2 * col_N; + A( numComps, i ) = factor2; + } + A( numComps, numComps ) = 0.0; + + // Pressure and temperature derivatives + for( integer ic = 0; ic < numComps; ++ic ) + { + real64 const phi2 = -phase2Composition[ic] * phase2Fugacity[ic]; + real64 const phi1 = phase1Composition[ic] * phase1Fugacity[ ic ]; + X( ic, Deriv::dP ) = phi2 * phase2LogFugacityDerivs( ic, Deriv::dP ) + + phi1 * phase1LogFugacityDerivs( ic, Deriv::dP ); + X( ic, Deriv::dT ) = phi2 * phase2LogFugacityDerivs( ic, Deriv::dT ) + + phi1 * phase1LogFugacityDerivs( ic, Deriv::dT ); + } + X( numComps, Deriv::dP ) = 0.0; + X( numComps, Deriv::dT ) = 0.0; - // Solve linear system - solveLinearSystem( A.toSlice(), X.toSlice() ); + // Composition derivatives + for( integer k = 0; k < numComps; ++k ) + { + integer const idof = Deriv::dC + k; - // Fill in the derivatives for( integer i = 0; i < numComps; ++i ) { - real64 const xi = liquidComposition[i]; - real64 const yi = vapourComposition[i]; - real64 const zi = composition[i]; - - for( integer const idof : {Deriv::dP, Deriv::dT} ) - { - real64 const dV = X( numComps, idof ); - real64 const dy = X( i, idof ); - real64 const dx = factor2*((xi - yi)*dV - V*dy); + real64 const phi_2_i = phase2Fugacity[i]; + real64 const xi = phase2Composition[i]; + real64 const zi = totalComposition[i]; - vapourFractionDerivs( idof ) = dV; - vapourCompositionDerivs( i, idof ) = dy; - liquidCompositionDerivs( i, idof ) = dx; - } + real64 row_i = 0.0; for( integer j = 0; j < numComps; ++j ) { - integer const idof = Deriv::dC+j; - real64 const dV = X( numComps, idof ); - real64 const dy = X( i, idof ); - real64 const dx = factor2*(-zi + (xi - yi)*dV - V*dy); - - vapourFractionDerivs( idof ) = dV; - vapourCompositionDerivs( i, idof ) = dy; - liquidCompositionDerivs( i, idof ) = dx; + row_i -= xi * phi_2_i * phase2LogFugacityDerivs( i, Deriv::dC + j ) * totalComposition[j]; } - liquidCompositionDerivs( i, Deriv::dC+i ) += factor2; + row_i += xi * phi_2_i * phase2LogFugacityDerivs( i, Deriv::dC + k ); + row_i -= phi_2_i * zi; + + X( i, idof ) = -factor2 * row_i; + } + X( k, idof ) -= factor2 * phase2Fugacity[k]; + X( numComps, idof ) = 0.0; + } + + // Solve linear system + solveLinearSystem( A.toSlice(), X.toSlice() ); + + // Fill in the derivatives + for( integer i = 0; i < numComps; ++i ) + { + real64 const xi = phase2Composition[i]; + real64 const yi = phase1Composition[i]; + real64 const zi = totalComposition[i]; + + for( integer const idof : {Deriv::dP, Deriv::dT} ) + { + real64 const dVL = X( numComps, idof ); + real64 const dy = X( i, idof ); + real64 const dx = factor2*((xi - yi)*dVL - VL*dy); + + phase1FractionDerivs( idof ) = dVL; + phase1CompositionDerivs( i, idof ) = dy; + phase2CompositionDerivs( i, idof ) = dx; + } + for( integer j = 0; j < numComps; ++j ) + { + integer const idof = Deriv::dC+j; + real64 const dVL = X( numComps, idof ); + real64 const dy = X( i, idof ); + real64 const dx = factor2*(-zi + (xi - yi)*dVL - VL*dy); + + phase1FractionDerivs( idof ) = dVL; + phase1CompositionDerivs( i, idof ) = dy; + phase2CompositionDerivs( i, idof ) = dx; } + phase2CompositionDerivs( i, Deriv::dC+i ) += factor2; } } diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp index 43b8f1a22b8..e68ed3689cd 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp @@ -80,8 +80,9 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate integer const numDofs = 2 + m_numComponents; - StackArray< real64, 2, maxNumComps > compositions( 1, m_numComponents ); + StackArray< real64, 2, 2*maxNumComps > compositions( 2, m_numComponents ); arraySlice1d< real64 > incipientComposition = compositions[0]; + arraySlice1d< real64 > tempComposition = compositions[1]; // Check if k-Values need to be initialised auto kVapourLiquid = kValues[0]; @@ -109,28 +110,55 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate } } - // Perform stability test to check that we have 2 phases integer const stabilityIterations = m_discreteFlashParameters[FlashParameters::STABILITY_MAX_ITERATIONS]; - real64 tangentPlaneDistance = 0.0; + real64 const stabilityThreshold = m_continuousFlashParameters[FlashParameters::STABILITY_THRESHOLD]; + + real64 tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; bool stabilityStatus = false; + EquationOfStateType stabilityEquationOfState = m_flashData.liquidEos; + if( 0 < stabilityIterations || needInitialisation ) { - stabilityStatus = StabilityTest::compute( m_numComponents, - pressure, - temperature, - compFraction, - componentProperties, - m_flashData.liquidEos, - m_flashData, - kVapourLiquid.toSliceConst(), - m_continuousFlashParameters.toSliceConst(), - m_discreteFlashParameters.toSliceConst(), - tangentPlaneDistance, - incipientComposition ); + EquationOfStateType const eos[2]{m_flashData.liquidEos, m_flashData.vapourEos}; + integer const numEos = (m_flashData.liquidEos == m_flashData.vapourEos) ? 1 : 2; + + for( integer eosIteration = 0; eosIteration < numEos; ++eosIteration ) + { + real64 tpd = 0.0; + bool const status = StabilityTest::compute( m_numComponents, + pressure, + temperature, + compFraction, + componentProperties, + eos[eosIteration], + m_flashData, + kVapourLiquid.toSliceConst(), + m_continuousFlashParameters.toSliceConst(), + m_discreteFlashParameters.toSliceConst(), + tpd, + tempComposition ); + stabilityStatus = stabilityStatus || status; + if( eosIteration == 1 && status ) + { + tangentPlaneDistance = LvArray::math::min( tangentPlaneDistance, tpd ); + } + else if( eosIteration == 0 ) + { + tangentPlaneDistance = tpd; + for( integer ic = 0; ic < m_numComponents; ++ic ) + { + incipientComposition[ic] = tempComposition[ic]; + } + + if( tangentPlaneDistance < stabilityThreshold ) + { + break; + } + } + } } // If the stability test failed to converge to a stationary point then we will assume the mixture is unstable - real64 const stabilityThreshold = m_continuousFlashParameters[FlashParameters::STABILITY_THRESHOLD]; if( tangentPlaneDistance < stabilityThreshold || !stabilityStatus ) { // Unstable mixture @@ -165,6 +193,29 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate phaseFraction.derivs[m_vapourIndex], phaseCompFraction.derivs[m_liquidIndex], phaseCompFraction.derivs[m_vapourIndex] ); + + // Handle the negative flash + integer singlePhaseIndex = -1; + real64 const & V = phaseFraction.value[m_vapourIndex]; + if( V < MultiFluidConstants::epsilon ) + { + singlePhaseIndex = m_liquidIndex; + } + else if( 1.0 - V < MultiFluidConstants::epsilon ) + { + singlePhaseIndex = m_vapourIndex; + } + if( 0 <= singlePhaseIndex ) + { + phaseFraction.value[m_vapourIndex] = (singlePhaseIndex == m_vapourIndex) ? 1.0 : 0.0; + LvArray::forValuesInSlice( phaseFraction.derivs[m_vapourIndex], setZero ); + LvArray::forValuesInSlice( phaseCompFraction.derivs[singlePhaseIndex], setZero ); + for( integer ic = 0; ic < m_numComponents; ++ic ) + { + phaseCompFraction.value( singlePhaseIndex, ic ) = compFraction[ic]; + phaseCompFraction.derivs( singlePhaseIndex, ic, Deriv::dC + ic ) = 1.0; + } + } } else { @@ -199,7 +250,7 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate temperature, compFraction, componentProperties, - m_flashData.liquidEos, + stabilityEquationOfState, m_flashData, incipientComposition.toSliceConst(), phaseCompFraction.derivs[incipientIndex], diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp index d3f6980d6bb..133edd3919d 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp @@ -117,13 +117,19 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< auto * equationOfState = const_cast< EquationOfState * >(m_parameters->get< EquationOfState >()); string eosName = EnumStrings< EquationOfStateType >::toString( EOS ); equationOfState->m_equationsOfStateNames.emplace_back( eosName ); - eosName = EnumStrings< EquationOfStateType >::toString( EquationOfStateType::PengRobinson ); + if constexpr (EOS == EquationOfStateType::SoreideWhitson) + { + eosName = EnumStrings< EquationOfStateType >::toString( EquationOfStateType::PengRobinson ); + } equationOfState->m_equationsOfStateNames.emplace_back( eosName ); auto * criticalVolume = const_cast< CriticalVolume * >(m_parameters->get< CriticalVolume >()); criticalVolume->m_componentCriticalVolume.resize( numComps ); TestFluid< NC >::populateArray( criticalVolume->m_componentCriticalVolume, this->m_fluid->criticalVolume ); + auto * flashParameters = const_cast< FlashParameters * >(m_parameters->get< FlashParameters >()); + flashParameters->m_continuousParameters[FlashParameters::STABILITY_TOLERANCE] = 1.0e-12; + m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::VAPOUR)); @@ -166,9 +172,6 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< PhasePropSlice( phaseFraction, dPhaseFraction ), PhaseCompSlice( phaseComponentFraction, dPhaseComponentFraction ) ); - ((void)expectedPhaseFraction); - ((void)expectedPhaseComponentFraction); - return; for( integer ip = 0; ip < numPhases; ip++ ) { checkRelativeError( phaseFraction[ip], expectedPhaseFraction[ip], relTol, absTol ); @@ -292,7 +295,7 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< sumZ += composition[jc]; } sumZ -= composition[ic]; - if( sumZ < absTol ) + if( sumZ < absTol || 1.0 - sumZ < absTol ) { continue; } @@ -311,6 +314,12 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< } } + void setStabilityThreshold( real64 const threshold ) + { + auto * flashParameters = const_cast< FlashParameters * >(m_parameters->get< FlashParameters >()); + flashParameters->m_continuousParameters[FlashParameters::STABILITY_THRESHOLD] = threshold; + } + protected: std::unique_ptr< TestFluid< NC > > m_fluid{}; std::unique_ptr< NegativeTwoPhaseFlashModel > m_flash{}; @@ -322,75 +331,93 @@ using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; using SoaveRedlichKwong2 = NegativeTwoPhaseFlashModelTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; using SoreideWhitson4 = NegativeTwoPhaseFlashModelTestFixture< 4, EquationOfStateType::SoreideWhitson >; -TEST_P( PengRobinson9, testFlashDerivatives ) +TEST_P( PengRobinson9, testFlash ) { testFlash( GetParam() ); } -TEST_P( SoaveRedlichKwong2, testFlashDerivatives ) +TEST_P( SoaveRedlichKwong2, testFlash ) { testFlash( GetParam() ); } -TEST_P( SoreideWhitson4, testFlashDerivatives ) +TEST_P( SoreideWhitson4, testFlash ) { testFlash( GetParam() ); } -/** - TEST_P( PengRobinson9, testFlashDerivatives ) - { - testFlashDerivatives( GetParam() ); - } - TEST_P( SoaveRedlichKwong2, testFlashDerivatives ) - { - testFlashDerivatives( GetParam() ); - } - TEST_P( SoreideWhitson4, testFlashDerivatives ) - { - testFlashDerivatives( GetParam() ); - } - */ + +TEST_P( PengRobinson9, testFlashDerivatives ) +{ + auto const param = GetParam(); + setStabilityThreshold( -1.0e-8 ); + testFlashDerivatives( param ); + setStabilityThreshold( 1.0e-8 ); + testFlashDerivatives( param ); +} +TEST_P( SoaveRedlichKwong2, testFlashDerivatives ) +{ + auto const param = GetParam(); + setStabilityThreshold( -1.0e-8 ); + testFlashDerivatives( param ); + setStabilityThreshold( 1.0e-8 ); + testFlashDerivatives( param ); +} +TEST_P( SoreideWhitson4, testFlashDerivatives ) +{ + auto const param = GetParam(); + setStabilityThreshold( -1.0e-8 ); + testFlashDerivatives( param ); + setStabilityThreshold( 1.0e-8 ); + testFlashDerivatives( param ); +} //------------------------------------------------------------------------------- // Data //------------------------------------------------------------------------------- + /* UNCRUSTIFY-OFF */ INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, PengRobinson9, ::testing::ValuesIn>({ - //{1.0000e+07, 293.15, {0.005499, 0.002225, 0.698843, 0.218062, 0.059526, 0.012000, 0.002131, 0.000613, 0.001100}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} - //{1.0000e+07, 293.15, {0.005499, 0.002225, 0.698836, 0.218062, 0.059526, 0.012000, 0.002131, 0.000613, 0.001107}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} - //{1.0000e+07, 293.15, {0.10900000, 0.00300000, 0.23470000, 0.11460000, 0.08790000, 0.04560000, 0.02090000, 0.01510000, 0.36920000}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} - {1.0000e+07, 293.15, {0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} - //{1.0000e+07, 293.15, {0.13701652, 0.00320982, 0.10906370, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883844}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} - //{1.0000e+07, 293.15, {0.13701652, 0.00320982, 0.10906370, 0.00000000, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.55543249}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} - //{1.0001e+07, 293.15, {0.13701652, 0.00320982, 0.10906376, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883838}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} - //FlashData<9>{1.0000e+07, 293.15, {0.00396181, 0.00219389, 0.58376764, 0.30883583, 0.06016813, 0.01165533, 0.00271459, 0.02656289, 0.00013988}, 0.185888, 0.414112, {0.000000, 0.111648, 0.551139}, {0.000000, 0.731628, 0.000000}} + {1.0e+07, 293.15, { 0.10900000, 0.00300000, 0.23470000, 0.11460000, 0.08790000, 0.04560000, 0.02090000, 0.01510000, 0.36920000 }, 0.78697508, 0.21302492, { 0.13701652, 0.08659405, 0.46883838 }, { 0.00549895, 0.21806200, 0.00110727 }}, + {1.0e+07, 333.15, { 0.00549900, 0.00222500, 0.69884300, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110000 }, 0.00000000, 1.00000000, { 0.00549901, 0.21806223, 0.00110000 }, { 0.00549900, 0.21806200, 0.00110000 }}, + {1.0e+07, 298.15, { 0.00549900, 0.00222500, 0.69883600, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110700 }, 0.00000000, 1.00000000, { 0.11827726, 0.08574692, 0.49905345 }, { 0.00549900, 0.21806200, 0.00110700 }}, + {1.0e+07, 288.15, { 0.00549900, 0.00222500, 0.69883600, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110700 }, 0.00054604, 0.99945396, { 0.16138581, 0.08705737, 0.43336991 }, { 0.00541384, 0.21813379, 0.00087084 }}, + {1.0e+07, 288.00, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 1.00000000, 0.00000000, { 0.13701652, 0.08659405, 0.46883834 }, { 0.00477313, 0.21542401, 0.00091472 }}, + {1.0e+07, 293.00, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 1.00000000, 0.00000000, { 0.13701652, 0.08659405, 0.46883834 }, { 0.00547668, 0.21798697, 0.00110119 }}, + {1.0e+07, 293.15, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 0.99999993, 0.00000007, { 0.13701653, 0.08659404, 0.46883837 }, { 0.00549895, 0.21806197, 0.00110727 }} }) ); - INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoreideWhitson4, ::testing::ValuesIn>({ - //{1.0e+07, 293.15, {0.000000, 0.000000, 0.000000, 1.000000}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} - //{1.0e+07, 293.15, {0.000005, 0.000005, 0.000005, 0.999985}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} - //{1.0e+07, 293.15, {0.000000, 1.000000, 0.000000, 0.000000}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} - //{1.0e+07, 293.15, {0.000005, 0.999985, 0.000005, 0.000005}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} - {1.0e+07, 293.15, {0.75, 0.05, 0.05, 0.15}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + {1.0e+07, 293.15, { 0.75000000, 0.05000000, 0.05000000, 0.15000000 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, + {1.0e+07, 288.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.88776183, 0.05226933, 0.00025588 }}, + {1.0e+07, 293.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99999974, 0.00000026, { 0.00143978, 0.00165799, 0.99682925 }, { 0.88234276, 0.05854960, 0.00035050 }}, + {1.0e+07, 353.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99948528, 0.00051472, { 0.00101790, 0.00159761, 0.99733896 }, { 0.82107330, 0.11891905, 0.00658930 }}, + {1.0e+07, 278.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00021799, 0.99978201, { 0.00172945, 0.00245159, 0.99572855 }, { 0.88247599, 0.05855523, 0.00013297 }}, + {1.0e+07, 293.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.00143967, 0.00165782, 0.99682944 }, { 0.88228400, 0.05854300, 0.00035000 }}, + {1.0e+07, 303.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.00827139, 0.00829367, 0.98303168 }, { 0.88228400, 0.05854300, 0.00035000 }}, + {1.0e+07, 293.15, { 0.00000000, 0.00000500, 0.00000000, 0.99999500 }, 1.00000000, 0.00000000, { 0.00000000, 0.00000500, 0.99999500 }, { 0.00000000, 0.00000500, 0.99999500 }}, + {1.0e+07, 293.15, { 0.00000000, 0.02572500, 0.00000000, 0.97427500 }, 1.00000000, 0.00000000, { 0.00000000, 0.02572500, 0.97427500 }, { 0.00000000, 0.99724814, 0.00275186 }}, + {1.0e+07, 293.15, { 0.00000000, 0.02572600, 0.00000000, 0.97427400 }, 0.99999969, 0.00000031, { 0.00000000, 0.02572570, 0.97427430 }, { 0.00000000, 0.99724814, 0.00275186 }}, + {1.0e+07, 293.15, { 0.99999500, 0.00000000, 0.00000000, 0.00000500 }, 0.00000000, 1.00000000, { 0.99999500, 0.00000000, 0.00000500 }, { 0.99999500, 0.00000000, 0.00000500 }}, + {1.0e+07, 288.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00008980, 0.99991020, { 0.00168896, 0.00000000, 0.99831104 }, { 0.99975363, 0.00000000, 0.00024637 }}, + {1.0e+07, 293.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.00160175, 0.00000000, 0.99839825 }, { 0.99966400, 0.00000000, 0.00033600 }}, + {1.0e+07, 303.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.00883712, 0.00000000, 0.99116288 }, { 0.99966400, 0.00000000, 0.00033600 }} }) ); INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoaveRedlichKwong2, ::testing::ValuesIn>({ - //{1.0e+07, 293.15, {0.000000, 0.000000, 0.000000, 1.000000}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} - //{1.0e+07, 293.15, {0.000005, 0.000005, 0.000005, 0.999985}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} - //{1.0e+07, 293.15, {0.000000, 1.000000, 0.000000, 0.000000}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} - //{1.0e+07, 293.15, {0.000005, 0.999985, 0.000005, 0.000005}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} - //{1.0e+07, 293.15, {0.75, 0.25}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} - //{1.0e+07, 293.15, {0.077600, 0.922400}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} - //{1.0e+07, 293.15, {0.1, 0.9}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} - {1.0e+07, 293.15, {0.0, 1.0}, 0.000000, 1.000000, {0.000000, 0.125000, 0.125000}, {0.000000, 0.125000, 0.125000}} + {1.0e+07, 293.15, { 0.75000000, 0.25000000 }, 0.26178317, 0.73821683, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }}, + {1.0e+07, 293.15, { 0.08178000, 0.91822000 }, 0.99999943, 0.00000057, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }}, + {1.0e+07, 293.15, { 0.08177900, 0.91822100 }, 1.00000000, 0.00000000, { 0.08177900, 0.91822100, 0.91822100 }, { 0.98696132, 0.01303868, 0.01303868 }}, + {1.0e+07, 293.15, { 0.08177800, 0.91822200 }, 1.00000000, 0.00000000, { 0.08177800, 0.91822200, 0.91822200 }, { 0.98696116, 0.01303884, 0.01303884 }}, + {1.0e+07, 293.15, { 0.98696200, 0.01303800 }, 0.00000000, 1.00000000, { 0.08178332, 0.91821668, 0.91821668 }, { 0.98696200, 0.01303800, 0.01303800 }}, + {1.0e+07, 293.15, { 0.98696100, 0.01303900 }, 0.00000044, 0.99999956, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }}, + {1.0e+07, 293.15, { 0.98696000, 0.01304000 }, 0.00000154, 0.99999846, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }} }) ); From 548d799e87c634676517f5f63d74250b4e29e63c Mon Sep 17 00:00:00 2001 From: dkachuma Date: Mon, 28 Jul 2025 16:52:11 -0500 Subject: [PATCH 10/28] Enable mass variables in compositional models --- .../CompositionalMultiphaseFluidUpdates.hpp | 21 +- .../constitutive/unitTests/CMakeLists.txt | 1 + ...FluidThreePhaseCompositionalMultiphase.cpp | 229 ++++++++++++++++++ ...tiFluidTwoPhaseCompositionalMultiphase.cpp | 9 +- 4 files changed, 250 insertions(+), 10 deletions(-) create mode 100644 src/coreComponents/constitutive/unitTests/testMultiFluidThreePhaseCompositionalMultiphase.cpp diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp index a50c92b90a6..8950139880a 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp @@ -350,18 +350,12 @@ CompositionalMultiphaseFluidUpdates< FLASH, PHASE1, PHASE2, PHASE3 >::compute( if( m_useMass ) { real64 phaseMolecularWeight[maxNumPhase]{}; - real64 dPhaseMolecularWeight[maxNumPhase][maxNumComp+2]{}; + real64 dPhaseMolecularWeight[maxNumPhase][maxNumDof]{}; arrayView1d< real64 const > const & componentMolarWeight = m_componentProperties.m_componentMolarWeight; for( integer ip = 0; ip < numPhase; ++ip ) { - phaseMolecularWeight[ip] = 0.0; - for( integer kc = 0; kc < numDof; ++kc ) - { - dPhaseMolecularWeight[ip][kc] = 0.0; - } - auto const & phaseComposition = phaseCompFrac.value[ip].toSliceConst(); auto const & dPhaseComposition = phaseCompFrac.derivs[ip].toSliceConst(); @@ -374,15 +368,26 @@ CompositionalMultiphaseFluidUpdates< FLASH, PHASE1, PHASE2, PHASE3 >::compute( } } } + convertToMassFractions( dCompMoleFrac_dCompMassFrac, phaseMolecularWeight, dPhaseMolecularWeight, phaseFrac, phaseCompFrac, - phaseDens.derivs, + phaseMassDensity.derivs, phaseVisc.derivs, phaseEnthalpy.derivs, phaseInternalEnergy.derivs ); + + // Molar density equals mass density + for( integer ip = 0; ip < numPhase; ++ip ) + { + phaseDens.value[ip] = phaseMassDensity.value[ip]; + for( integer idof = 0; idof < numDof; ++idof ) + { + phaseDens.derivs( ip, idof ) = phaseMassDensity.derivs( ip, idof ); + } + } } // 7. Compute total fluid mass/molar density and derivatives diff --git a/src/coreComponents/constitutive/unitTests/CMakeLists.txt b/src/coreComponents/constitutive/unitTests/CMakeLists.txt index 426d4bb34fb..dd39d9c88fa 100644 --- a/src/coreComponents/constitutive/unitTests/CMakeLists.txt +++ b/src/coreComponents/constitutive/unitTests/CMakeLists.txt @@ -19,6 +19,7 @@ set( gtest_geosx_tests testModifiedCamClay.cpp testMultiFluidBlackOil.cpp testMultiFluidCO2Brine.cpp + testMultiFluidThreePhaseCompositionalMultiphase.cpp testMultiFluidTwoPhaseCompositionalMultiphase.cpp testMultiFluidDeadOil.cpp testMultiFluidSelector.cpp diff --git a/src/coreComponents/constitutive/unitTests/testMultiFluidThreePhaseCompositionalMultiphase.cpp b/src/coreComponents/constitutive/unitTests/testMultiFluidThreePhaseCompositionalMultiphase.cpp new file mode 100644 index 00000000000..879c10ffe1a --- /dev/null +++ b/src/coreComponents/constitutive/unitTests/testMultiFluidThreePhaseCompositionalMultiphase.cpp @@ -0,0 +1,229 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file testMultiFluidTwoPhaseCompositionalMultiphase.cpp + */ + +#include "FluidModelTest.hpp" +#include "constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluid.hpp" +#include "constitutive/fluid/multifluid/compositional/parameters/ImmiscibleWaterParameters.hpp" +#include "common/initializeEnvironment.hpp" + +using namespace geos::constitutive; +using namespace geos::constitutive::compositional; + +namespace geos +{ +namespace testing +{ + +template< integer NUM_COMP > +struct FluidData +{}; + +template< typename TEST_TYPE > +class MultiFluidCompositionalMultiphaseTestFixture : public FluidModelTest< CompositionalThreePhaseLohrenzBrayClarkViscosity, std::tuple_element_t< 1, TEST_TYPE >::value, 3 > +{ +public: + static constexpr EquationOfStateType EquationOfState = std::tuple_element_t< 0, TEST_TYPE >::value; + using Base = FluidModelTest< CompositionalThreePhaseLohrenzBrayClarkViscosity, std::tuple_element_t< 1, TEST_TYPE >::value, 3 >; + static constexpr real64 relTol = 1.0e-4; + static constexpr real64 absTol = 1.0e-3; + +public: + MultiFluidCompositionalMultiphaseTestFixture() + { + Base::createFluid( getFluidName(), []( CompositionalThreePhaseLohrenzBrayClarkViscosity & fluid ){ + fillPhysicalProperties( fluid ); + } ); + } + + ~MultiFluidCompositionalMultiphaseTestFixture() override = default; + + void testNumericalDerivatives( const bool useMass ) + { + CompositionalThreePhaseLohrenzBrayClarkViscosity * fluid = this->getFluid( this->getFluidName() ); + + fluid->setMassFlag( useMass ); + + array2d< real64 > samples; + FluidData< Base::numComp >::getSamples( samples ); + integer const sampleCount = samples.size( 0 ); + Feed< Base::numComp > sample; + + real64 constexpr eps = 1.0e-7; + + constexpr real64 pressures[] = { 10.0e5, 50.0e5, 100.0e5, 600.0e5 }; + constexpr real64 temperatures[] = { 15.5, 24.0, 40.0, 80.0 }; + + for( integer sampleIndex = 0; sampleIndex < sampleCount; ++sampleIndex ) + { + for( integer ic = 0; ic < Base::numComp; ++ic ) + { + sample[ic] = samples( sampleIndex, ic ); + } + for( real64 const pressure : pressures ) + { + for( real64 const temperature : temperatures ) + { + typename Base::TestPoint const data ( pressure, units::convertCToK( temperature ), sample ); + Base::testNumericalDerivatives( fluid, data, eps, relTol, absTol ); + } + } + } + } + + static string getFluidName(); + +private: + static void fillPhysicalProperties( CompositionalThreePhaseLohrenzBrayClarkViscosity & fluid ); +}; + +template< typename TEST_TYPE > +string MultiFluidCompositionalMultiphaseTestFixture< TEST_TYPE >::getFluidName() +{ + return GEOS_FMT( "fluid_{}_{}", + Base::numComp, + EnumStrings< EquationOfStateType >::toString( EquationOfState ) ); +} + +template< integer NUM_COMP > +static void fillBinaryCoeffs( array2d< real64 > & binaryCoeff, std::array< real64 const, NUM_COMP *(NUM_COMP-1)/2 > const data ) +{ + auto bic = data.begin(); + binaryCoeff.resize( NUM_COMP, NUM_COMP ); + for( integer i = 0; i < NUM_COMP; ++i ) + { + binaryCoeff( i, i ) = 0.0; + for( integer j = i+1; j < NUM_COMP; ++j ) + { + binaryCoeff( i, j ) = *bic++; + binaryCoeff( j, i ) = binaryCoeff( i, j ); + } + } +} + +template< integer NUM_COMP > +static void populateArray( arraySlice1d< real64 > array, std::array< real64 const, NUM_COMP > const data ) +{ + for( integer i = 0; i < NUM_COMP; ++i ) + { + array[i] = data[i]; + } +} + +template<> +struct FluidData< 4 > +{ + static void fillProperties( dataRepository::Group & fluid ) + { + using Keys = typename CompositionalThreePhaseLohrenzBrayClarkViscosity::viewKeyStruct; + + auto testFluid = TestFluid< 4 >::create( {Fluid::N2, Fluid::CO2, Fluid::H2O, Fluid::CH4} ); + + string_array & componentNames = fluid.getReference< string_array >( Keys::componentNamesString() ); + componentNames = testFluid->componentNames; + + array1d< real64 > & molarWeight = fluid.getReference< array1d< real64 > >( Keys::componentMolarWeightString() ); + TestFluid< 4 >::createArray( molarWeight, testFluid->molecularWeight ); + array1d< real64 > & criticalPressure = fluid.getReference< array1d< real64 > >( Keys::componentCriticalPressureString() ); + TestFluid< 4 >::createArray( criticalPressure, testFluid->criticalPressure ); + array1d< real64 > & criticalTemperature = fluid.getReference< array1d< real64 > >( Keys::componentCriticalTemperatureString() ); + TestFluid< 4 >::createArray( criticalTemperature, testFluid->criticalTemperature ); + array1d< real64 > & acentricFactor = fluid.getReference< array1d< real64 > >( Keys::componentAcentricFactorString() ); + TestFluid< 4 >::createArray( acentricFactor, testFluid->acentricFactor ); + } + + static void getSamples( array2d< real64 > & samples ) + { + samples.resize( 3, 4 ); + populateArray< 4 >( samples[0], {0.099, 0.300, 0.600, 0.001} ); + populateArray< 4 >( samples[1], {0.350, 0.350, 0.200, 0.100} ); + populateArray< 4 >( samples[2], {0.050, 0.050, 0.100, 0.800} ); + } +}; + +template< typename TEST_TYPE > +void MultiFluidCompositionalMultiphaseTestFixture< TEST_TYPE >::fillPhysicalProperties( CompositionalThreePhaseLohrenzBrayClarkViscosity & fluid ) +{ + string_array & phaseNames = fluid.template getReference< string_array >( MultiFluidBase::viewKeyStruct::phaseNamesString() ); + phaseNames = {"oil", "gas", "water"}; + + string const eosName = EnumStrings< EquationOfStateType >::toString( EquationOfState ); + string_array & equationOfState = fluid.template getReference< string_array >( EquationOfState::viewKeyStruct::equationsOfStateString() ); + equationOfState = {eosName, eosName, eosName}; + + dataRepository::Group & group = fluid; + FluidData< Base::numComp >::fillProperties( group ); + + // Water properties + using WaterKeys = typename ImmiscibleWaterParameters::viewKeyStruct; + real64 & waterDensity = fluid.template getReference< real64 >( WaterKeys::waterDensityString() ); + waterDensity = 1020.0; + real64 & waterCompressibility = fluid.template getReference< real64 >( WaterKeys::waterCompressibilityString() ); + waterCompressibility = 4.4e-10; + real64 & waterViscosity = fluid.template getReference< real64 >( WaterKeys::waterViscosityString() ); + waterViscosity = 5.4650e-04; +} + +template< EquationOfStateType EOS, integer NUM_COMP > +using TestType = std::tuple< + std::integral_constant< EquationOfStateType, EOS >, + std::integral_constant< integer, NUM_COMP > + >; + +using TestTypes = ::testing::Types< + TestType< EquationOfStateType::PengRobinson, 4 >, + TestType< EquationOfStateType::SoaveRedlichKwong, 4 > + >; + +class NameGenerator +{ +public: + template< typename T > + static std::string GetName( int index ) + { + return GEOS_FMT( "CompositionalFluid_{}_{}", MultiFluidCompositionalMultiphaseTestFixture< T >::getFluidName(), index ); + } +}; + +TYPED_TEST_SUITE( MultiFluidCompositionalMultiphaseTestFixture, TestTypes, NameGenerator ); + +TYPED_TEST( MultiFluidCompositionalMultiphaseTestFixture, numericalDerivativesMolar ) +{ + this->testNumericalDerivatives( false ); +} + +TYPED_TEST( MultiFluidCompositionalMultiphaseTestFixture, numericalDerivativesMass ) +{ + this->testNumericalDerivatives( true ); +} + +} // testing +} // geos + +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + + geos::setupEnvironment( argc, argv ); + + int const result = RUN_ALL_TESTS(); + + geos::cleanupEnvironment(); + + return result; +} diff --git a/src/coreComponents/constitutive/unitTests/testMultiFluidTwoPhaseCompositionalMultiphase.cpp b/src/coreComponents/constitutive/unitTests/testMultiFluidTwoPhaseCompositionalMultiphase.cpp index 90f1e1b7aef..b26f3541648 100644 --- a/src/coreComponents/constitutive/unitTests/testMultiFluidTwoPhaseCompositionalMultiphase.cpp +++ b/src/coreComponents/constitutive/unitTests/testMultiFluidTwoPhaseCompositionalMultiphase.cpp @@ -86,7 +86,7 @@ class MultiFluidCompositionalMultiphaseTestFixture : public FluidModelTest< real64 constexpr eps = 1.0e-7; - constexpr real64 pressures[] = { 1.0e5, 50.0e5, 100.0e5, 600.0e5 }; + constexpr real64 pressures[] = { 10.0e5, 50.0e5, 100.0e5, 600.0e5 }; constexpr real64 temperatures[] = { 15.5, 24.0, 40.0, 80.0 }; for( integer sampleIndex = 0; sampleIndex < sampleCount; ++sampleIndex ) @@ -254,11 +254,16 @@ class NameGenerator TYPED_TEST_SUITE( MultiFluidCompositionalMultiphaseTestFixture, TestTypes, NameGenerator ); -TYPED_TEST( MultiFluidCompositionalMultiphaseTestFixture, numericalDerivatives ) +TYPED_TEST( MultiFluidCompositionalMultiphaseTestFixture, numericalDerivativesMolar ) { this->testNumericalDerivatives( false ); } +TYPED_TEST( MultiFluidCompositionalMultiphaseTestFixture, numericalDerivativesMass ) +{ + this->testNumericalDerivatives( true ); +} + } // testing } // geos From 01e7259d48623edc72485a15cdb48325c66725dc Mon Sep 17 00:00:00 2001 From: dkachuma Date: Mon, 28 Jul 2025 17:03:11 -0500 Subject: [PATCH 11/28] Update driver test --- ...stPVT_ThreePhaseCompositional_blackOil.txt | 202 +++++++++--------- 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/src/coreComponents/unitTests/constitutiveTests/testPVT_ThreePhaseCompositional_blackOil.txt b/src/coreComponents/unitTests/constitutiveTests/testPVT_ThreePhaseCompositional_blackOil.txt index 53e20dce320..6bf59be5458 100644 --- a/src/coreComponents/unitTests/constitutiveTests/testPVT_ThreePhaseCompositional_blackOil.txt +++ b/src/coreComponents/unitTests/constitutiveTests/testPVT_ThreePhaseCompositional_blackOil.txt @@ -10,104 +10,104 @@ # columns 18-20 = oil phase fractions [C1, C7+, H2O] # columns 21-23 = gas phase fractions [C1, C7+, H2O] # columns 24-26 = water phase fractions [C1, C7+, H2O] -0.0000e+00 3.5000e+07 5.5315e+02 6.1560e+03 6.0169e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.5295e+03 5.5295e+03 5.6953e+04 5.2265e+02 5.2265e+02 1.0257e+03 1.0240e-04 1.0240e-04 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -2.0000e-02 3.4000e+07 5.5315e+02 6.1183e+03 6.2707e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.4953e+03 5.4953e+03 5.6930e+04 5.1941e+02 5.1941e+02 1.0253e+03 1.0027e-04 1.0027e-04 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -4.0000e-02 3.3000e+07 5.5315e+02 6.0792e+03 6.5439e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.4598e+03 5.4598e+03 5.6906e+04 5.1606e+02 5.1606e+02 1.0249e+03 9.8135e-05 9.8135e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -6.0000e-02 3.2000e+07 5.5315e+02 6.0387e+03 6.8385e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.4230e+03 5.4230e+03 5.6882e+04 5.1258e+02 5.1258e+02 1.0245e+03 9.6007e-05 9.6007e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -8.0000e-02 3.1000e+07 5.5315e+02 5.9966e+03 7.1573e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.3847e+03 5.3847e+03 5.6859e+04 5.0896e+02 5.0896e+02 1.0240e+03 9.3883e-05 9.3883e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.0000e-01 3.0000e+07 5.5315e+02 5.9528e+03 7.5032e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.3450e+03 5.3450e+03 5.6835e+04 5.0521e+02 5.0521e+02 1.0236e+03 9.1761e-05 9.1761e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.2000e-01 2.9000e+07 5.5315e+02 5.9072e+03 7.8796e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.3036e+03 5.3036e+03 5.6812e+04 5.0129e+02 5.0129e+02 1.0232e+03 8.9642e-05 8.9642e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.4000e-01 2.8000e+07 5.5315e+02 5.8597e+03 8.2906e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.2604e+03 5.2604e+03 5.6788e+04 4.9721e+02 4.9721e+02 1.0228e+03 8.7525e-05 8.7525e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.6000e-01 2.7000e+07 5.5315e+02 5.8100e+03 8.7412e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.2153e+03 5.2153e+03 5.6765e+04 4.9295e+02 4.9295e+02 1.0223e+03 8.5409e-05 8.5409e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.8000e-01 2.6000e+07 5.5315e+02 5.7580e+03 9.2370e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.1682e+03 5.1682e+03 5.6741e+04 4.8849e+02 4.8849e+02 1.0219e+03 8.3293e-05 8.3293e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -2.0000e-01 2.5000e+07 5.5315e+02 5.7036e+03 9.7851e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.1187e+03 5.1187e+03 5.6717e+04 4.8382e+02 4.8382e+02 1.0215e+03 8.1175e-05 8.1175e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -2.2000e-01 2.4000e+07 5.5315e+02 5.6174e+03 1.7179e-08 8.8110e-01 6.1877e-03 1.1271e-01 5.0414e+03 4.9180e+03 5.6694e+04 4.8521e+02 1.3086e+02 1.0211e+03 8.1572e-05 2.1495e-05 3.2929e-04 4.8901e-01 5.1099e-01 0.0000e+00 9.3267e-01 6.7327e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -2.4000e-01 2.3000e+07 5.5315e+02 5.5204e+03 1.7647e-08 8.7325e-01 1.4036e-02 1.1271e-01 4.9562e+03 4.7398e+03 5.6670e+04 4.8864e+02 1.2549e+02 1.0206e+03 8.2813e-05 2.1134e-05 3.2929e-04 4.7405e-01 5.2595e-01 0.0000e+00 9.3352e-01 6.6484e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -2.6000e-01 2.2000e+07 5.5315e+02 5.4225e+03 1.8162e-08 8.6581e-01 2.1475e-02 1.1271e-01 4.8719e+03 4.5585e+03 5.6647e+04 4.9205e+02 1.2016e+02 1.0202e+03 8.4061e-05 2.0788e-05 3.2929e-04 4.5873e-01 5.4127e-01 0.0000e+00 9.3426e-01 6.5741e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -2.8000e-01 2.1000e+07 5.5315e+02 5.3234e+03 1.8732e-08 8.5874e-01 2.8551e-02 1.1271e-01 4.7885e+03 4.3743e+03 5.6623e+04 4.9543e+02 1.1486e+02 1.0198e+03 8.5316e-05 2.0456e-05 3.2929e-04 4.4303e-01 5.5697e-01 0.0000e+00 9.3490e-01 6.5103e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -3.0000e-01 2.0000e+07 5.5315e+02 5.2230e+03 1.9369e-08 8.5198e-01 3.5311e-02 1.1271e-01 4.7061e+03 4.1872e+03 5.6600e+04 4.9880e+02 1.0961e+02 1.0194e+03 8.6578e-05 2.0139e-05 3.2929e-04 4.2693e-01 5.7307e-01 0.0000e+00 9.3542e-01 6.4579e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -3.2000e-01 1.9000e+07 5.5315e+02 5.1210e+03 2.0089e-08 8.4549e-01 4.1796e-02 1.1271e-01 4.6246e+03 3.9973e+03 5.6576e+04 5.0214e+02 1.0438e+02 1.0189e+03 8.7844e-05 1.9835e-05 3.2929e-04 4.1042e-01 5.8958e-01 0.0000e+00 9.3582e-01 6.4178e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -3.4000e-01 1.8000e+07 5.5315e+02 5.0171e+03 2.0911e-08 8.3924e-01 4.8049e-02 1.1271e-01 4.5439e+03 3.8047e+03 5.6553e+04 5.0547e+02 9.9197e+01 1.0185e+03 8.9115e-05 1.9544e-05 3.2929e-04 3.9347e-01 6.0653e-01 0.0000e+00 9.3609e-01 6.3914e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -3.6000e-01 1.7000e+07 5.5315e+02 4.9110e+03 2.1861e-08 8.3318e-01 5.4111e-02 1.1271e-01 4.4641e+03 3.6096e+03 5.6530e+04 5.0878e+02 9.4045e+01 1.0181e+03 9.0389e-05 1.9265e-05 3.2929e-04 3.7608e-01 6.2392e-01 0.0000e+00 9.3620e-01 6.3802e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -3.8000e-01 1.6000e+07 5.5315e+02 4.8022e+03 2.2976e-08 8.2726e-01 6.0026e-02 1.1271e-01 4.3852e+03 3.4119e+03 5.6506e+04 5.1208e+02 8.8928e+01 1.0177e+03 9.1664e-05 1.8998e-05 3.2929e-04 3.5822e-01 6.4178e-01 0.0000e+00 9.3614e-01 6.3864e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -4.0000e-01 1.5000e+07 5.5315e+02 4.6901e+03 2.4303e-08 8.2145e-01 6.5840e-02 1.1271e-01 4.3071e+03 3.2118e+03 5.6483e+04 5.1536e+02 8.3846e+01 1.0173e+03 9.2939e-05 1.8741e-05 3.2929e-04 3.3987e-01 6.6013e-01 0.0000e+00 9.3587e-01 6.4127e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -4.2000e-01 1.4000e+07 5.5315e+02 4.5740e+03 2.5910e-08 8.1568e-01 7.1608e-02 1.1271e-01 4.2299e+03 3.0095e+03 5.6459e+04 5.1864e+02 7.8800e+01 1.0168e+03 9.4210e-05 1.8494e-05 3.2929e-04 3.2102e-01 6.7898e-01 0.0000e+00 9.3537e-01 6.4625e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -4.4000e-01 1.3000e+07 5.5315e+02 4.4527e+03 2.7893e-08 8.0990e-01 7.7391e-02 1.1271e-01 4.1535e+03 2.8050e+03 5.6436e+04 5.2190e+02 7.3789e+01 1.0164e+03 9.5475e-05 1.8255e-05 3.2929e-04 3.0163e-01 6.9837e-01 0.0000e+00 9.3459e-01 6.5406e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -4.6000e-01 1.2000e+07 5.5315e+02 4.3251e+03 3.0392e-08 8.0402e-01 8.3265e-02 1.1271e-01 4.0779e+03 2.5984e+03 5.6412e+04 5.2516e+02 6.8814e+01 1.0160e+03 9.6732e-05 1.8022e-05 3.2929e-04 2.8170e-01 7.1830e-01 0.0000e+00 9.3347e-01 6.6532e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -4.8000e-01 1.1000e+07 5.5315e+02 4.1891e+03 3.3618e-08 7.9796e-01 8.9328e-02 1.1271e-01 4.0031e+03 2.3899e+03 5.6389e+04 5.2841e+02 6.3876e+01 1.0156e+03 9.7975e-05 1.7795e-05 3.2929e-04 2.6120e-01 7.3880e-01 0.0000e+00 9.3191e-01 6.8088e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -5.0000e-01 1.0000e+07 5.5315e+02 4.0424e+03 3.7901e-08 7.9158e-01 9.5711e-02 1.1271e-01 3.9291e+03 2.1796e+03 5.6366e+04 5.3165e+02 5.8976e+01 1.0151e+03 9.9202e-05 1.7569e-05 3.2929e-04 2.4011e-01 7.5989e-01 0.0000e+00 9.2981e-01 7.0194e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -5.2000e-01 9.6040e+06 5.5315e+02 3.9806e+03 3.9996e-08 7.8892e-01 9.8365e-02 1.1271e-01 3.9000e+03 2.0959e+03 5.6356e+04 5.3293e+02 5.7046e+01 1.0150e+03 9.9682e-05 1.7479e-05 3.2929e-04 2.3159e-01 7.6841e-01 0.0000e+00 9.2878e-01 7.1215e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -5.4000e-01 9.2080e+06 5.5315e+02 3.9162e+03 4.2382e-08 7.8618e-01 1.0111e-01 1.1271e-01 3.8710e+03 2.0119e+03 5.6347e+04 5.3421e+02 5.5122e+01 1.0148e+03 1.0016e-04 1.7389e-05 3.2929e-04 2.2297e-01 7.7703e-01 0.0000e+00 9.2764e-01 7.2363e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -5.6000e-01 8.8120e+06 5.5315e+02 3.8490e+03 4.5115e-08 7.8332e-01 1.0397e-01 1.1271e-01 3.8422e+03 1.9277e+03 5.6338e+04 5.3549e+02 5.3205e+01 1.0146e+03 1.0063e-04 1.7299e-05 3.2929e-04 2.1425e-01 7.8575e-01 0.0000e+00 9.2635e-01 7.3653e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -5.8000e-01 8.4160e+06 5.5315e+02 3.7785e+03 4.8266e-08 7.8033e-01 1.0696e-01 1.1271e-01 3.8135e+03 1.8432e+03 5.6329e+04 5.3677e+02 5.1293e+01 1.0145e+03 1.0110e-04 1.7207e-05 3.2929e-04 2.0543e-01 7.9457e-01 0.0000e+00 9.2489e-01 7.5105e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -6.0000e-01 8.0200e+06 5.5315e+02 3.7044e+03 5.1924e-08 7.7719e-01 1.1010e-01 1.1271e-01 3.7849e+03 1.7585e+03 5.6319e+04 5.3805e+02 4.9388e+01 1.0143e+03 1.0156e-04 1.7113e-05 3.2929e-04 1.9650e-01 8.0350e-01 0.0000e+00 9.2326e-01 7.6743e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -6.2000e-01 7.6240e+06 5.5315e+02 3.6260e+03 5.6202e-08 7.7386e-01 1.1343e-01 1.1271e-01 3.7565e+03 1.6736e+03 5.6310e+04 5.3933e+02 4.7489e+01 1.0141e+03 1.0202e-04 1.7018e-05 3.2929e-04 1.8748e-01 8.1252e-01 0.0000e+00 9.2141e-01 7.8594e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -6.4000e-01 7.2280e+06 5.5315e+02 3.5428e+03 6.1247e-08 7.7031e-01 1.1698e-01 1.1271e-01 3.7281e+03 1.5884e+03 5.6301e+04 5.4061e+02 4.5597e+01 1.0140e+03 1.0247e-04 1.6920e-05 3.2929e-04 1.7834e-01 8.2166e-01 0.0000e+00 9.1931e-01 8.0692e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -6.6000e-01 6.8320e+06 5.5315e+02 3.4539e+03 6.7247e-08 7.6650e-01 1.2079e-01 1.1271e-01 3.6999e+03 1.5031e+03 5.6292e+04 5.4188e+02 4.3711e+01 1.0138e+03 1.0292e-04 1.6818e-05 3.2929e-04 1.6910e-01 8.3090e-01 0.0000e+00 9.1692e-01 8.3080e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -6.8000e-01 6.4360e+06 5.5315e+02 3.3585e+03 7.4453e-08 7.6236e-01 1.2493e-01 1.1271e-01 3.6718e+03 1.4176e+03 5.6282e+04 5.4316e+02 4.1832e+01 1.0136e+03 1.0335e-04 1.6713e-05 3.2929e-04 1.5975e-01 8.4025e-01 0.0000e+00 9.1419e-01 8.5810e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -7.0000e-01 6.0400e+06 5.5315e+02 3.2554e+03 8.3199e-08 7.5783e-01 1.2946e-01 1.1271e-01 3.6438e+03 1.3319e+03 5.6273e+04 5.4443e+02 3.9959e+01 1.0135e+03 1.0379e-04 1.6602e-05 3.2929e-04 1.5029e-01 8.4971e-01 0.0000e+00 9.1105e-01 8.8948e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -7.2000e-01 5.6440e+06 5.5315e+02 3.1435e+03 9.3938e-08 7.5281e-01 1.3448e-01 1.1271e-01 3.6160e+03 1.2460e+03 5.6264e+04 5.4570e+02 3.8093e+01 1.0133e+03 1.0421e-04 1.6485e-05 3.2929e-04 1.4071e-01 8.5929e-01 0.0000e+00 9.0742e-01 9.2579e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -7.4000e-01 5.2480e+06 5.5315e+02 3.0210e+03 1.0730e-07 7.4718e-01 1.4011e-01 1.1271e-01 3.5883e+03 1.1600e+03 5.6255e+04 5.4698e+02 3.6233e+01 1.0131e+03 1.0463e-04 1.6359e-05 3.2929e-04 1.3102e-01 8.6898e-01 0.0000e+00 9.0319e-01 9.6812e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -7.6000e-01 4.8520e+06 5.5315e+02 2.8861e+03 1.2415e-07 7.4077e-01 1.4652e-01 1.1271e-01 3.5607e+03 1.0738e+03 5.6245e+04 5.4825e+02 3.4381e+01 1.0130e+03 1.0503e-04 1.6224e-05 3.2929e-04 1.2122e-01 8.7878e-01 0.0000e+00 8.9821e-01 1.0179e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -7.8000e-01 4.4560e+06 5.5315e+02 2.7364e+03 1.4578e-07 7.3336e-01 1.5393e-01 1.1271e-01 3.5332e+03 9.8750e+02 5.6236e+04 5.4952e+02 3.2535e+01 1.0128e+03 1.0543e-04 1.6076e-05 3.2929e-04 1.1129e-01 8.8871e-01 0.0000e+00 8.9228e-01 1.0772e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -8.0000e-01 4.0600e+06 5.5315e+02 2.5691e+03 1.7403e-07 7.2461e-01 1.6268e-01 1.1271e-01 3.5058e+03 9.0104e+02 5.6227e+04 5.5079e+02 3.0696e+01 1.0126e+03 1.0582e-04 1.5911e-05 3.2929e-04 1.0125e-01 8.9875e-01 0.0000e+00 8.8514e-01 1.1486e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -8.2000e-01 3.6640e+06 5.5315e+02 2.3811e+03 2.1172e-07 7.1406e-01 1.7323e-01 1.1271e-01 3.4786e+03 8.1446e+02 5.6218e+04 5.5206e+02 2.8865e+01 1.0125e+03 1.0619e-04 1.5725e-05 3.2929e-04 9.1082e-02 9.0892e-01 0.0000e+00 8.7640e-01 1.2360e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -8.4000e-01 3.2680e+06 5.5315e+02 2.1686e+03 2.6326e-07 7.0095e-01 1.8634e-01 1.1271e-01 3.4515e+03 7.2776e+02 5.6208e+04 5.5333e+02 2.7040e+01 1.0123e+03 1.0656e-04 1.5512e-05 3.2929e-04 8.0792e-02 9.1921e-01 0.0000e+00 8.6548e-01 1.3452e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -8.6000e-01 2.8720e+06 5.5315e+02 1.9276e+03 3.3583e-07 6.8411e-01 2.0318e-01 1.1271e-01 3.4245e+03 6.4096e+02 5.6199e+04 5.5460e+02 2.5222e+01 1.0121e+03 1.0691e-04 1.5261e-05 3.2929e-04 7.0376e-02 9.2962e-01 0.0000e+00 8.5148e-01 1.4852e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -8.8000e-01 2.4760e+06 5.5315e+02 1.6549e+03 4.4172e-07 6.6146e-01 2.2583e-01 1.1271e-01 3.3976e+03 5.5407e+02 5.6190e+04 5.5587e+02 2.3412e+01 1.0120e+03 1.0725e-04 1.4958e-05 3.2929e-04 5.9832e-02 9.4017e-01 0.0000e+00 8.3298e-01 1.6702e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -9.0000e-01 2.0800e+06 5.5315e+02 1.3487e+03 6.0350e-07 6.2908e-01 2.5821e-01 1.1271e-01 3.3708e+03 4.6709e+02 5.6181e+04 5.5714e+02 2.1609e+01 1.0118e+03 1.0757e-04 1.4583e-05 3.2929e-04 4.9159e-02 9.5084e-01 0.0000e+00 8.0745e-01 1.9255e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -9.2000e-01 1.6840e+06 5.5315e+02 1.0126e+03 8.6704e-07 5.7850e-01 3.0879e-01 1.1271e-01 3.3442e+03 3.8004e+02 5.6172e+04 5.5841e+02 1.9813e+01 1.0116e+03 1.0788e-04 1.4097e-05 3.2929e-04 3.8354e-02 9.6165e-01 0.0000e+00 7.7004e-01 2.2996e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -9.4000e-01 1.2880e+06 5.5315e+02 6.6052e+02 1.3428e-06 4.8744e-01 3.9985e-01 1.1271e-01 3.3176e+03 2.9292e+02 5.6162e+04 5.5968e+02 1.8025e+01 1.0115e+03 1.0818e-04 1.3437e-05 3.2929e-04 2.7415e-02 9.7259e-01 0.0000e+00 7.1015e-01 2.8985e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -9.6000e-01 8.9200e+05 5.5315e+02 3.2534e+02 2.3985e-06 2.7229e-01 6.1500e-01 1.1271e-01 3.2912e+03 2.0575e+02 5.6153e+04 5.6094e+02 1.6244e+01 1.0113e+03 1.0845e-04 1.2477e-05 3.2929e-04 1.6340e-02 9.8366e-01 0.0000e+00 5.9920e-01 4.0080e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -9.8000e-01 4.9600e+05 5.5315e+02 1.2779e+02 2.1211e-06 8.8729e-01 0.0000e+00 1.1271e-01 1.1342e+02 1.1342e+02 5.6144e+04 1.0720e+01 1.0720e+01 1.0112e+03 1.1716e-05 1.1716e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.0000e+00 1.0000e+05 5.5315e+02 2.4746e+01 1.0099e-05 8.8729e-01 0.0000e+00 1.1271e-01 2.1958e+01 2.1958e+01 5.6135e+04 2.0755e+00 2.0755e+00 1.0110e+03 1.1560e-05 1.1560e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.0200e+00 4.9600e+05 5.8315e+02 1.2012e+02 2.1009e-06 8.8729e-01 0.0000e+00 1.1271e-01 1.0660e+02 1.0660e+02 5.6144e+04 1.0076e+01 1.0076e+01 1.0112e+03 1.2221e-05 1.2221e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.0400e+00 8.9200e+05 5.8315e+02 2.2354e+02 1.2093e-06 8.8729e-01 0.0000e+00 1.1271e-01 1.9843e+02 1.9843e+02 5.6153e+04 1.8756e+01 1.8756e+01 1.0113e+03 1.2405e-05 1.2405e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.0600e+00 1.2880e+06 5.8315e+02 3.4774e+02 1.7667e-06 4.3627e-02 8.4366e-01 1.1271e-01 3.0621e+03 2.9504e+02 5.6162e+04 5.1804e+02 2.7265e+01 1.0115e+03 8.2939e-05 1.2695e-05 3.2929e-04 2.4366e-02 9.7563e-01 0.0000e+00 5.1344e-01 4.8656e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.0800e+00 1.6840e+06 5.8315e+02 6.0704e+02 1.1265e-06 3.0186e-01 5.8543e-01 1.1271e-01 3.0890e+03 3.7828e+02 5.6172e+04 5.1649e+02 2.9209e+01 1.0116e+03 8.2756e-05 1.3409e-05 3.2929e-04 3.6932e-02 9.6307e-01 0.0000e+00 6.1026e-01 3.8974e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.1000e+00 2.0800e+06 5.8315e+02 8.8181e+02 7.8965e-07 4.2838e-01 4.5891e-01 1.1271e-01 3.1161e+03 4.6143e+02 5.6181e+04 5.1495e+02 3.1163e+01 1.0118e+03 8.2556e-05 1.3965e-05 3.2929e-04 4.9339e-02 9.5066e-01 0.0000e+00 6.7192e-01 3.2808e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.1200e+00 2.4760e+06 5.8315e+02 1.1539e+03 5.8364e-07 5.0379e-01 3.8350e-01 1.1271e-01 3.1432e+03 5.4447e+02 5.6190e+04 5.1339e+02 3.3128e+01 1.0120e+03 8.2339e-05 1.4414e-05 3.2929e-04 6.1589e-02 9.3841e-01 0.0000e+00 7.1454e-01 2.8546e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.1400e+00 2.8720e+06 5.8315e+02 1.4127e+03 4.4720e-07 5.5409e-01 3.3320e-01 1.1271e-01 3.1706e+03 6.2740e+02 5.6199e+04 5.1184e+02 3.5105e+01 1.0121e+03 8.2106e-05 1.4788e-05 3.2929e-04 7.3685e-02 9.2632e-01 0.0000e+00 7.4571e-01 2.5429e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.1600e+00 3.2680e+06 5.8315e+02 1.6532e+03 3.5221e-07 5.9019e-01 2.9710e-01 1.1271e-01 3.1980e+03 7.1021e+02 5.6208e+04 5.1028e+02 3.7093e+01 1.0123e+03 8.1860e-05 1.5107e-05 3.2929e-04 8.5630e-02 9.1437e-01 0.0000e+00 7.6944e-01 2.3056e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.1800e+00 3.6640e+06 5.8315e+02 1.8738e+03 2.8372e-07 6.1751e-01 2.6978e-01 1.1271e-01 3.2257e+03 7.9289e+02 5.6218e+04 5.0871e+02 3.9092e+01 1.0125e+03 8.1599e-05 1.5383e-05 3.2929e-04 9.7426e-02 9.0257e-01 0.0000e+00 7.8808e-01 2.1192e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.2000e+00 4.0600e+06 5.8315e+02 2.0746e+03 2.3298e-07 6.3902e-01 2.4827e-01 1.1271e-01 3.2534e+03 8.7543e+02 5.6227e+04 5.0714e+02 4.1103e+01 1.0126e+03 8.1325e-05 1.5628e-05 3.2929e-04 1.0908e-01 8.9092e-01 0.0000e+00 8.0306e-01 1.9694e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.2200e+00 4.4560e+06 5.8315e+02 2.2571e+03 1.9456e-07 6.5648e-01 2.3081e-01 1.1271e-01 3.2813e+03 9.5783e+02 5.6236e+04 5.0557e+02 4.3124e+01 1.0128e+03 8.1039e-05 1.5847e-05 3.2929e-04 1.2058e-01 8.7942e-01 0.0000e+00 8.1535e-01 1.8465e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.2400e+00 4.8520e+06 5.8315e+02 2.4230e+03 1.6492e-07 6.7102e-01 2.1627e-01 1.1271e-01 3.3094e+03 1.0401e+03 5.6245e+04 5.0399e+02 4.5158e+01 1.0130e+03 8.0742e-05 1.6047e-05 3.2929e-04 1.3195e-01 8.6805e-01 0.0000e+00 8.2557e-01 1.7443e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.2600e+00 5.2480e+06 5.8315e+02 2.5742e+03 1.4168e-07 6.8338e-01 2.0390e-01 1.1271e-01 3.3376e+03 1.1221e+03 5.6255e+04 5.0240e+02 4.7203e+01 1.0131e+03 8.0433e-05 1.6230e-05 3.2929e-04 1.4318e-01 8.5682e-01 0.0000e+00 8.3419e-01 1.6581e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.2800e+00 5.6440e+06 5.8315e+02 2.7125e+03 1.2319e-07 6.9409e-01 1.9320e-01 1.1271e-01 3.3660e+03 1.2040e+03 5.6264e+04 5.0081e+02 4.9259e+01 1.0133e+03 8.0115e-05 1.6401e-05 3.2929e-04 1.5427e-01 8.4573e-01 0.0000e+00 8.4154e-01 1.5846e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.3000e+00 6.0400e+06 5.8315e+02 2.8394e+03 1.0830e-07 7.0351e-01 1.8378e-01 1.1271e-01 3.3945e+03 1.2857e+03 5.6273e+04 4.9921e+02 5.1327e+01 1.0135e+03 7.9786e-05 1.6561e-05 3.2929e-04 1.6523e-01 8.3477e-01 0.0000e+00 8.4786e-01 1.5214e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.3200e+00 6.4360e+06 5.8315e+02 2.9565e+03 9.6164e-08 7.1191e-01 1.7538e-01 1.1271e-01 3.4232e+03 1.3673e+03 5.6282e+04 4.9761e+02 5.3407e+01 1.0136e+03 7.9448e-05 1.6713e-05 3.2929e-04 1.7606e-01 8.2394e-01 0.0000e+00 8.5333e-01 1.4667e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.3400e+00 6.8320e+06 5.8315e+02 3.0649e+03 8.6168e-08 7.1948e-01 1.6781e-01 1.1271e-01 3.4520e+03 1.4486e+03 5.6292e+04 4.9600e+02 5.5498e+01 1.0138e+03 7.9102e-05 1.6858e-05 3.2929e-04 1.8676e-01 8.1324e-01 0.0000e+00 8.5811e-01 1.4189e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.3600e+00 7.2280e+06 5.8315e+02 3.1660e+03 7.7854e-08 7.2640e-01 1.6089e-01 1.1271e-01 3.4809e+03 1.5297e+03 5.6301e+04 4.9439e+02 5.7601e+01 1.0140e+03 7.8748e-05 1.6997e-05 3.2929e-04 1.9733e-01 8.0267e-01 0.0000e+00 8.6229e-01 1.3771e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.3800e+00 7.6240e+06 5.8315e+02 3.2605e+03 7.0879e-08 7.3276e-01 1.5453e-01 1.1271e-01 3.5101e+03 1.6106e+03 5.6310e+04 4.9277e+02 5.9717e+01 1.0141e+03 7.8386e-05 1.7132e-05 3.2929e-04 2.0778e-01 7.9222e-01 0.0000e+00 8.6597e-01 1.3403e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.4000e+00 8.0200e+06 5.8315e+02 3.3492e+03 6.4979e-08 7.3868e-01 1.4861e-01 1.1271e-01 3.5394e+03 1.6913e+03 5.6319e+04 4.9114e+02 6.1844e+01 1.0143e+03 7.8016e-05 1.7263e-05 3.2929e-04 2.1811e-01 7.8189e-01 0.0000e+00 8.6923e-01 1.3077e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.4200e+00 8.4160e+06 5.8315e+02 3.4330e+03 5.9949e-08 7.4422e-01 1.4307e-01 1.1271e-01 3.5688e+03 1.7717e+03 5.6329e+04 4.8951e+02 6.3983e+01 1.0145e+03 7.7640e-05 1.7391e-05 3.2929e-04 2.2831e-01 7.7169e-01 0.0000e+00 8.7211e-01 1.2789e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.4400e+00 8.8120e+06 5.8315e+02 3.5124e+03 5.5632e-08 7.4946e-01 1.3783e-01 1.1271e-01 3.5984e+03 1.8519e+03 5.6338e+04 4.8787e+02 6.6135e+01 1.0146e+03 7.7258e-05 1.7517e-05 3.2929e-04 2.3840e-01 7.6160e-01 0.0000e+00 8.7467e-01 1.2533e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.4600e+00 9.2080e+06 5.8315e+02 3.5880e+03 5.1902e-08 7.5444e-01 1.3285e-01 1.1271e-01 3.6282e+03 1.9319e+03 5.6347e+04 4.8623e+02 6.8299e+01 1.0148e+03 7.6869e-05 1.7641e-05 3.2929e-04 2.4838e-01 7.5162e-01 0.0000e+00 8.7695e-01 1.2305e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.4800e+00 9.6040e+06 5.8315e+02 3.6601e+03 4.8659e-08 7.5920e-01 1.2809e-01 1.1271e-01 3.6581e+03 2.0115e+03 5.6356e+04 4.8457e+02 7.0476e+01 1.0150e+03 7.6475e-05 1.7765e-05 3.2929e-04 2.5824e-01 7.4176e-01 0.0000e+00 8.7898e-01 1.2102e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.5000e+00 1.0000e+07 5.8315e+02 3.7291e+03 4.5824e-08 7.6378e-01 1.2351e-01 1.1271e-01 3.6882e+03 2.0910e+03 5.6366e+04 4.8291e+02 7.2665e+01 1.0151e+03 7.6075e-05 1.7888e-05 3.2929e-04 2.6799e-01 7.3201e-01 0.0000e+00 8.8078e-01 1.1922e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.5200e+00 1.1000e+07 5.8315e+02 3.8922e+03 4.0073e-08 7.7474e-01 1.1254e-01 1.1271e-01 3.7648e+03 2.2903e+03 5.6389e+04 4.7869e+02 7.8250e+01 1.0156e+03 7.5043e-05 1.8197e-05 3.2929e-04 2.9214e-01 7.0786e-01 0.0000e+00 8.8451e-01 1.1549e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.5400e+00 1.2000e+07 5.8315e+02 4.0423e+03 3.5793e-08 7.8515e-01 1.0214e-01 1.1271e-01 3.8426e+03 2.4877e+03 5.6412e+04 4.7441e+02 8.3920e+01 1.0160e+03 7.3984e-05 1.8510e-05 3.2929e-04 3.1562e-01 6.8438e-01 0.0000e+00 8.8727e-01 1.1273e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.5600e+00 1.3000e+07 5.8315e+02 4.1824e+03 3.2518e-08 7.9527e-01 9.2016e-02 1.1271e-01 3.9214e+03 2.6831e+03 5.6436e+04 4.7007e+02 8.9678e+01 1.0164e+03 7.2901e-05 1.8830e-05 3.2929e-04 3.3847e-01 6.6153e-01 0.0000e+00 8.8925e-01 1.1075e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.5800e+00 1.4000e+07 5.8315e+02 4.3149e+03 2.9952e-08 8.0535e-01 8.1944e-02 1.1271e-01 4.0014e+03 2.8763e+03 5.6459e+04 4.6568e+02 9.5527e+01 1.0168e+03 7.1797e-05 1.9161e-05 3.2929e-04 3.6073e-01 6.3927e-01 0.0000e+00 8.9060e-01 1.0940e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.6000e+00 1.5000e+07 5.8315e+02 4.4414e+03 2.7899e-08 8.1555e-01 7.1735e-02 1.1271e-01 4.0824e+03 3.0673e+03 5.6483e+04 4.6121e+02 1.0147e+02 1.0173e+03 7.0674e-05 1.9505e-05 3.2929e-04 3.8242e-01 6.1758e-01 0.0000e+00 8.9143e-01 1.0857e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.6200e+00 1.6000e+07 5.8315e+02 4.5631e+03 2.6223e-08 8.2607e-01 6.1222e-02 1.1271e-01 4.1647e+03 3.2559e+03 5.6506e+04 4.5668e+02 1.0752e+02 1.0177e+03 6.9535e-05 1.9866e-05 3.2929e-04 4.0358e-01 5.9642e-01 0.0000e+00 8.9180e-01 1.0820e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.6400e+00 1.7000e+07 5.8315e+02 4.6810e+03 2.4832e-08 8.3705e-01 5.0240e-02 1.1271e-01 4.2481e+03 3.4420e+03 5.6530e+04 4.5206e+02 1.1367e+02 1.0181e+03 6.8382e-05 2.0245e-05 3.2929e-04 4.2423e-01 5.7577e-01 0.0000e+00 8.9179e-01 1.0821e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.6600e+00 1.8000e+07 5.8315e+02 4.7958e+03 2.3660e-08 8.4867e-01 3.8624e-02 1.1271e-01 4.3328e+03 3.6254e+03 5.6553e+04 4.4735e+02 1.1994e+02 1.0185e+03 6.7214e-05 2.0645e-05 3.2929e-04 4.4441e-01 5.5559e-01 0.0000e+00 8.9142e-01 1.0858e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.6800e+00 1.9000e+07 5.8315e+02 4.9081e+03 2.2657e-08 8.6110e-01 2.6192e-02 1.1271e-01 4.4188e+03 3.8061e+03 5.6576e+04 4.4254e+02 1.2633e+02 1.0189e+03 6.6034e-05 2.1068e-05 3.2929e-04 4.6414e-01 5.3586e-01 0.0000e+00 8.9072e-01 1.0928e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.7000e+00 2.0000e+07 5.8315e+02 5.0183e+03 2.1788e-08 8.7455e-01 1.2742e-02 1.1271e-01 4.5061e+03 3.9839e+03 5.6600e+04 4.3761e+02 1.3286e+02 1.0194e+03 6.4840e-05 2.1517e-05 3.2929e-04 4.8347e-01 5.1653e-01 0.0000e+00 8.8972e-01 1.1028e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.7200e+00 2.1000e+07 5.8315e+02 5.1233e+03 1.5507e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.5927e+03 4.5927e+03 5.6623e+04 4.3410e+02 4.3410e+02 1.0198e+03 6.4038e-05 6.4038e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.7400e+00 2.2000e+07 5.8315e+02 5.2003e+03 1.4379e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.6625e+03 4.6625e+03 5.6647e+04 4.4069e+02 4.4069e+02 1.0202e+03 6.5972e-05 6.5972e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.7600e+00 2.3000e+07 5.8315e+02 5.2730e+03 1.3388e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.7283e+03 4.7283e+03 5.6670e+04 4.4691e+02 4.4691e+02 1.0206e+03 6.7891e-05 6.7891e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.7800e+00 2.4000e+07 5.8315e+02 5.3417e+03 1.2511e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.7905e+03 4.7905e+03 5.6694e+04 4.5280e+02 4.5280e+02 1.0211e+03 6.9797e-05 6.9797e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.8000e+00 2.5000e+07 5.8315e+02 5.4068e+03 1.1730e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.8495e+03 4.8495e+03 5.6717e+04 4.5837e+02 4.5837e+02 1.0215e+03 7.1695e-05 7.1695e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.8200e+00 2.6000e+07 5.8315e+02 5.4686e+03 1.1031e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.9055e+03 4.9055e+03 5.6741e+04 4.6367e+02 4.6367e+02 1.0219e+03 7.3587e-05 7.3587e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.8400e+00 2.7000e+07 5.8315e+02 5.5275e+03 1.0402e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.9589e+03 4.9589e+03 5.6765e+04 4.6872e+02 4.6872e+02 1.0223e+03 7.5475e-05 7.5475e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.8600e+00 2.8000e+07 5.8315e+02 5.5837e+03 9.8334e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.0099e+03 5.0099e+03 5.6788e+04 4.7353e+02 4.7353e+02 1.0228e+03 7.7360e-05 7.7360e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.8800e+00 2.9000e+07 5.8315e+02 5.6374e+03 9.3169e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.0586e+03 5.0586e+03 5.6812e+04 4.7814e+02 4.7814e+02 1.0232e+03 7.9245e-05 7.9245e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.9000e+00 3.0000e+07 5.8315e+02 5.6888e+03 8.8460e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.1052e+03 5.1052e+03 5.6835e+04 4.8254e+02 4.8254e+02 1.0236e+03 8.1131e-05 8.1131e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.9200e+00 3.1000e+07 5.8315e+02 5.7381e+03 8.4151e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.1499e+03 5.1499e+03 5.6859e+04 4.8677e+02 4.8677e+02 1.0240e+03 8.3018e-05 8.3018e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.9400e+00 3.2000e+07 5.8315e+02 5.7854e+03 8.0196e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.1929e+03 5.1929e+03 5.6882e+04 4.9083e+02 4.9083e+02 1.0245e+03 8.4907e-05 8.4907e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.9600e+00 3.3000e+07 5.8315e+02 5.8309e+03 7.6552e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.2342e+03 5.2342e+03 5.6906e+04 4.9473e+02 4.9473e+02 1.0249e+03 8.6800e-05 8.6800e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -1.9800e+00 3.4000e+07 5.8315e+02 5.8747e+03 7.3187e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.2739e+03 5.2739e+03 5.6930e+04 4.9849e+02 4.9849e+02 1.0253e+03 8.8696e-05 8.8696e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 -2.0000e+00 3.5000e+07 5.8315e+02 5.9169e+03 7.0071e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.3122e+03 5.3122e+03 5.6953e+04 5.0211e+02 5.0211e+02 1.0257e+03 9.0597e-05 9.0597e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 0.0000e+00 3.5000e+07 5.5315e+02 5.5323e+02 5.7413e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.2265e+02 5.2265e+02 1.0257e+03 5.2265e+02 5.2265e+02 1.0257e+03 1.0240e-04 1.0240e-04 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 2.0000e-02 3.4000e+07 5.5315e+02 5.5000e+02 5.9841e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.1941e+02 5.1941e+02 1.0253e+03 5.1941e+02 5.1941e+02 1.0253e+03 1.0027e-04 1.0027e-04 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 4.0000e-02 3.3000e+07 5.5315e+02 5.4665e+02 6.2456e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.1606e+02 5.1606e+02 1.0249e+03 5.1606e+02 5.1606e+02 1.0249e+03 9.8135e-05 9.8135e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 6.0000e-02 3.2000e+07 5.5315e+02 5.4317e+02 6.5278e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.1258e+02 5.1258e+02 1.0245e+03 5.1258e+02 5.1258e+02 1.0245e+03 9.6007e-05 9.6007e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 8.0000e-02 3.1000e+07 5.5315e+02 5.3955e+02 6.8332e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.0896e+02 5.0896e+02 1.0240e+03 5.0896e+02 5.0896e+02 1.0240e+03 9.3883e-05 9.3883e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.0000e-01 3.0000e+07 5.5315e+02 5.3579e+02 7.1647e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.0521e+02 5.0521e+02 1.0236e+03 5.0521e+02 5.0521e+02 1.0236e+03 9.1761e-05 9.1761e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.2000e-01 2.9000e+07 5.5315e+02 5.3187e+02 7.5256e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.0129e+02 5.0129e+02 1.0232e+03 5.0129e+02 5.0129e+02 1.0232e+03 8.9642e-05 8.9642e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.4000e-01 2.8000e+07 5.5315e+02 5.2778e+02 7.9198e-09 8.8729e-01 0.0000e+00 1.1271e-01 4.9721e+02 4.9721e+02 1.0228e+03 4.9721e+02 4.9721e+02 1.0228e+03 8.7525e-05 8.7525e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.6000e-01 2.7000e+07 5.5315e+02 5.2351e+02 8.3522e-09 8.8729e-01 0.0000e+00 1.1271e-01 4.9295e+02 4.9295e+02 1.0223e+03 4.9295e+02 4.9295e+02 1.0223e+03 8.5409e-05 8.5409e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.8000e-01 2.6000e+07 5.5315e+02 5.1903e+02 8.8282e-09 8.8729e-01 0.0000e+00 1.1271e-01 4.8849e+02 4.8849e+02 1.0219e+03 4.8849e+02 4.8849e+02 1.0219e+03 8.3293e-05 8.3293e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 2.0000e-01 2.5000e+07 5.5315e+02 5.1433e+02 9.3546e-09 8.8729e-01 0.0000e+00 1.1271e-01 4.8382e+02 4.8382e+02 1.0215e+03 4.8382e+02 4.8382e+02 1.0215e+03 8.1175e-05 8.1175e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 2.2000e-01 2.4000e+07 5.5315e+02 5.0669e+02 1.7298e-08 8.8110e-01 6.1877e-03 1.1271e-01 4.8521e+02 1.3086e+02 1.0211e+03 4.8521e+02 1.3086e+02 1.0211e+03 8.1572e-05 2.1495e-05 3.2929e-04 4.8901e-01 5.1099e-01 0.0000e+00 9.3267e-01 6.7327e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 2.4000e-01 2.3000e+07 5.5315e+02 4.9766e+02 1.8677e-08 8.7325e-01 1.4036e-02 1.1271e-01 4.8864e+02 1.2549e+02 1.0206e+03 4.8864e+02 1.2549e+02 1.0206e+03 8.2813e-05 2.1134e-05 3.2929e-04 4.7405e-01 5.2595e-01 0.0000e+00 9.3352e-01 6.6484e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 2.6000e-01 2.2000e+07 5.5315e+02 4.8809e+02 2.0212e-08 8.6581e-01 2.1475e-02 1.1271e-01 4.9205e+02 1.2016e+02 1.0202e+03 4.9205e+02 1.2016e+02 1.0202e+03 8.4061e-05 2.0788e-05 3.2929e-04 4.5873e-01 5.4127e-01 0.0000e+00 9.3426e-01 6.5741e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 2.8000e-01 2.1000e+07 5.5315e+02 4.7792e+02 2.1927e-08 8.5874e-01 2.8551e-02 1.1271e-01 4.9543e+02 1.1486e+02 1.0198e+03 4.9543e+02 1.1486e+02 1.0198e+03 8.5316e-05 2.0456e-05 3.2929e-04 4.4303e-01 5.5697e-01 0.0000e+00 9.3490e-01 6.5103e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 3.0000e-01 2.0000e+07 5.5315e+02 4.6711e+02 2.3850e-08 8.5198e-01 3.5311e-02 1.1271e-01 4.9880e+02 1.0961e+02 1.0194e+03 4.9880e+02 1.0961e+02 1.0194e+03 8.6578e-05 2.0139e-05 3.2929e-04 4.2693e-01 5.7307e-01 0.0000e+00 9.3542e-01 6.4579e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 3.2000e-01 1.9000e+07 5.5315e+02 4.5562e+02 2.6018e-08 8.4549e-01 4.1796e-02 1.1271e-01 5.0214e+02 1.0438e+02 1.0189e+03 5.0214e+02 1.0438e+02 1.0189e+03 8.7844e-05 1.9835e-05 3.2929e-04 4.1042e-01 5.8958e-01 0.0000e+00 9.3582e-01 6.4178e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 3.4000e-01 1.8000e+07 5.5315e+02 4.4339e+02 2.8473e-08 8.3924e-01 4.8049e-02 1.1271e-01 5.0547e+02 9.9197e+01 1.0185e+03 5.0547e+02 9.9197e+01 1.0185e+03 8.9115e-05 1.9544e-05 3.2929e-04 3.9347e-01 6.0653e-01 0.0000e+00 9.3609e-01 6.3914e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 3.6000e-01 1.7000e+07 5.5315e+02 4.3035e+02 3.1270e-08 8.3318e-01 5.4111e-02 1.1271e-01 5.0878e+02 9.4045e+01 1.0181e+03 5.0878e+02 9.4045e+01 1.0181e+03 9.0389e-05 1.9265e-05 3.2929e-04 3.7608e-01 6.2392e-01 0.0000e+00 9.3620e-01 6.3802e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 3.8000e-01 1.6000e+07 5.5315e+02 4.1645e+02 3.4476e-08 8.2726e-01 6.0026e-02 1.1271e-01 5.1208e+02 8.8928e+01 1.0177e+03 5.1208e+02 8.8928e+01 1.0177e+03 9.1664e-05 1.8998e-05 3.2929e-04 3.5822e-01 6.4178e-01 0.0000e+00 9.3614e-01 6.3864e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 4.0000e-01 1.5000e+07 5.5315e+02 4.0161e+02 3.8180e-08 8.2145e-01 6.5840e-02 1.1271e-01 5.1536e+02 8.3846e+01 1.0173e+03 5.1536e+02 8.3846e+01 1.0173e+03 9.2939e-05 1.8741e-05 3.2929e-04 3.3987e-01 6.6013e-01 0.0000e+00 9.3587e-01 6.4127e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 4.2000e-01 1.4000e+07 5.5315e+02 3.8575e+02 4.2494e-08 8.1568e-01 7.1608e-02 1.1271e-01 5.1864e+02 7.8800e+01 1.0168e+03 5.1864e+02 7.8800e+01 1.0168e+03 9.4210e-05 1.8494e-05 3.2929e-04 3.2102e-01 6.7898e-01 0.0000e+00 9.3537e-01 6.4625e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 4.4000e-01 1.3000e+07 5.5315e+02 3.6880e+02 4.7566e-08 8.0990e-01 7.7391e-02 1.1271e-01 5.2190e+02 7.3789e+01 1.0164e+03 5.2190e+02 7.3789e+01 1.0164e+03 9.5475e-05 1.8255e-05 3.2929e-04 3.0163e-01 6.9837e-01 0.0000e+00 9.3459e-01 6.5406e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 4.6000e-01 1.2000e+07 5.5315e+02 3.5064e+02 5.3595e-08 8.0402e-01 8.3265e-02 1.1271e-01 5.2516e+02 6.8814e+01 1.0160e+03 5.2516e+02 6.8814e+01 1.0160e+03 9.6732e-05 1.8022e-05 3.2929e-04 2.8170e-01 7.1830e-01 0.0000e+00 9.3347e-01 6.6532e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 4.8000e-01 1.1000e+07 5.5315e+02 3.3117e+02 6.0857e-08 7.9796e-01 8.9328e-02 1.1271e-01 5.2841e+02 6.3876e+01 1.0156e+03 5.2841e+02 6.3876e+01 1.0156e+03 9.7975e-05 1.7795e-05 3.2929e-04 2.6120e-01 7.3880e-01 0.0000e+00 9.3191e-01 6.8088e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 5.0000e-01 1.0000e+07 5.5315e+02 3.1029e+02 6.9742e-08 7.9158e-01 9.5711e-02 1.1271e-01 5.3165e+02 5.8976e+01 1.0151e+03 5.3165e+02 5.8976e+01 1.0151e+03 9.9202e-05 1.7569e-05 3.2929e-04 2.4011e-01 7.5989e-01 0.0000e+00 9.2981e-01 7.0194e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 5.2000e-01 9.6040e+06 5.5315e+02 3.0159e+02 7.3826e-08 7.8892e-01 9.8365e-02 1.1271e-01 5.3293e+02 5.7046e+01 1.0150e+03 5.3293e+02 5.7046e+01 1.0150e+03 9.9682e-05 1.7479e-05 3.2929e-04 2.3159e-01 7.6841e-01 0.0000e+00 9.2878e-01 7.1215e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 5.4000e-01 9.2080e+06 5.5315e+02 2.9265e+02 7.8297e-08 7.8618e-01 1.0111e-01 1.1271e-01 5.3421e+02 5.5122e+01 1.0148e+03 5.3421e+02 5.5122e+01 1.0148e+03 1.0016e-04 1.7389e-05 3.2929e-04 2.2297e-01 7.7703e-01 0.0000e+00 9.2764e-01 7.2363e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 5.6000e-01 8.8120e+06 5.5315e+02 2.8344e+02 8.3209e-08 7.8332e-01 1.0397e-01 1.1271e-01 5.3549e+02 5.3205e+01 1.0146e+03 5.3549e+02 5.3205e+01 1.0146e+03 1.0063e-04 1.7299e-05 3.2929e-04 2.1425e-01 7.8575e-01 0.0000e+00 9.2635e-01 7.3653e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 5.8000e-01 8.4160e+06 5.5315e+02 2.7397e+02 8.8627e-08 7.8033e-01 1.0696e-01 1.1271e-01 5.3677e+02 5.1293e+01 1.0145e+03 5.3677e+02 5.1293e+01 1.0145e+03 1.0110e-04 1.7207e-05 3.2929e-04 2.0543e-01 7.9457e-01 0.0000e+00 9.2489e-01 7.5105e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 6.0000e-01 8.0200e+06 5.5315e+02 2.6421e+02 9.4631e-08 7.7719e-01 1.1010e-01 1.1271e-01 5.3805e+02 4.9388e+01 1.0143e+03 5.3805e+02 4.9388e+01 1.0143e+03 1.0156e-04 1.7113e-05 3.2929e-04 1.9650e-01 8.0350e-01 0.0000e+00 9.2326e-01 7.6743e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 6.2000e-01 7.6240e+06 5.5315e+02 2.5416e+02 1.0132e-07 7.7386e-01 1.1343e-01 1.1271e-01 5.3933e+02 4.7489e+01 1.0141e+03 5.3933e+02 4.7489e+01 1.0141e+03 1.0202e-04 1.7018e-05 3.2929e-04 1.8748e-01 8.1252e-01 0.0000e+00 9.2141e-01 7.8594e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 6.4000e-01 7.2280e+06 5.5315e+02 2.4381e+02 1.0880e-07 7.7031e-01 1.1698e-01 1.1271e-01 5.4061e+02 4.5597e+01 1.0140e+03 5.4061e+02 4.5597e+01 1.0140e+03 1.0247e-04 1.6920e-05 3.2929e-04 1.7834e-01 8.2166e-01 0.0000e+00 9.1931e-01 8.0692e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 6.6000e-01 6.8320e+06 5.5315e+02 2.3315e+02 1.1723e-07 7.6650e-01 1.2079e-01 1.1271e-01 5.4188e+02 4.3711e+01 1.0138e+03 5.4188e+02 4.3711e+01 1.0138e+03 1.0292e-04 1.6818e-05 3.2929e-04 1.6910e-01 8.3090e-01 0.0000e+00 9.1692e-01 8.3080e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 6.8000e-01 6.4360e+06 5.5315e+02 2.2216e+02 1.2680e-07 7.6236e-01 1.2493e-01 1.1271e-01 5.4316e+02 4.1832e+01 1.0136e+03 5.4316e+02 4.1832e+01 1.0136e+03 1.0335e-04 1.6713e-05 3.2929e-04 1.5975e-01 8.4025e-01 0.0000e+00 9.1419e-01 8.5810e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 7.0000e-01 6.0400e+06 5.5315e+02 2.1083e+02 1.3773e-07 7.5783e-01 1.2946e-01 1.1271e-01 5.4443e+02 3.9959e+01 1.0135e+03 5.4443e+02 3.9959e+01 1.0135e+03 1.0379e-04 1.6602e-05 3.2929e-04 1.5029e-01 8.4971e-01 0.0000e+00 9.1105e-01 8.8948e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 7.2000e-01 5.6440e+06 5.5315e+02 1.9916e+02 1.5033e-07 7.5281e-01 1.3448e-01 1.1271e-01 5.4570e+02 3.8093e+01 1.0133e+03 5.4570e+02 3.8093e+01 1.0133e+03 1.0421e-04 1.6485e-05 3.2929e-04 1.4071e-01 8.5929e-01 0.0000e+00 9.0742e-01 9.2579e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 7.4000e-01 5.2480e+06 5.5315e+02 1.8712e+02 1.6501e-07 7.4718e-01 1.4011e-01 1.1271e-01 5.4698e+02 3.6233e+01 1.0131e+03 5.4698e+02 3.6233e+01 1.0131e+03 1.0463e-04 1.6359e-05 3.2929e-04 1.3102e-01 8.6898e-01 0.0000e+00 9.0319e-01 9.6812e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 7.6000e-01 4.8520e+06 5.5315e+02 1.7470e+02 1.8232e-07 7.4077e-01 1.4652e-01 1.1271e-01 5.4825e+02 3.4381e+01 1.0130e+03 5.4825e+02 3.4381e+01 1.0130e+03 1.0503e-04 1.6224e-05 3.2929e-04 1.2122e-01 8.7878e-01 0.0000e+00 8.9821e-01 1.0179e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 7.8000e-01 4.4560e+06 5.5315e+02 1.6189e+02 2.0300e-07 7.3336e-01 1.5393e-01 1.1271e-01 5.4952e+02 3.2535e+01 1.0128e+03 5.4952e+02 3.2535e+01 1.0128e+03 1.0543e-04 1.6076e-05 3.2929e-04 1.1129e-01 8.8871e-01 0.0000e+00 8.9228e-01 1.0772e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 8.0000e-01 4.0600e+06 5.5315e+02 1.4867e+02 2.2814e-07 7.2461e-01 1.6268e-01 1.1271e-01 5.5079e+02 3.0696e+01 1.0126e+03 5.5079e+02 3.0696e+01 1.0126e+03 1.0582e-04 1.5911e-05 3.2929e-04 1.0125e-01 8.9875e-01 0.0000e+00 8.8514e-01 1.1486e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 8.2000e-01 3.6640e+06 5.5315e+02 1.3502e+02 2.5932e-07 7.1406e-01 1.7323e-01 1.1271e-01 5.5206e+02 2.8865e+01 1.0125e+03 5.5206e+02 2.8865e+01 1.0125e+03 1.0619e-04 1.5725e-05 3.2929e-04 9.1082e-02 9.0892e-01 0.0000e+00 8.7640e-01 1.2360e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 8.4000e-01 3.2680e+06 5.5315e+02 1.2093e+02 2.9896e-07 7.0095e-01 1.8634e-01 1.1271e-01 5.5333e+02 2.7040e+01 1.0123e+03 5.5333e+02 2.7040e+01 1.0123e+03 1.0656e-04 1.5512e-05 3.2929e-04 8.0792e-02 9.1921e-01 0.0000e+00 8.6548e-01 1.3452e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 8.6000e-01 2.8720e+06 5.5315e+02 1.0638e+02 3.5103e-07 6.8411e-01 2.0318e-01 1.1271e-01 5.5460e+02 2.5222e+01 1.0121e+03 5.5460e+02 2.5222e+01 1.0121e+03 1.0691e-04 1.5261e-05 3.2929e-04 7.0376e-02 9.2962e-01 0.0000e+00 8.5148e-01 1.4852e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 8.8000e-01 2.4760e+06 5.5315e+02 9.1349e+01 4.2233e-07 6.6146e-01 2.2583e-01 1.1271e-01 5.5587e+02 2.3412e+01 1.0120e+03 5.5587e+02 2.3412e+01 1.0120e+03 1.0725e-04 1.4958e-05 3.2929e-04 5.9832e-02 9.4017e-01 0.0000e+00 8.3298e-01 1.6702e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 9.0000e-01 2.0800e+06 5.5315e+02 7.5818e+01 5.2586e-07 6.2908e-01 2.5821e-01 1.1271e-01 5.5714e+02 2.1609e+01 1.0118e+03 5.5714e+02 2.1609e+01 1.0118e+03 1.0757e-04 1.4583e-05 3.2929e-04 4.9159e-02 9.5084e-01 0.0000e+00 8.0745e-01 1.9255e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 9.2000e-01 1.6840e+06 5.5315e+02 5.9765e+01 6.8961e-07 5.7850e-01 3.0879e-01 1.1271e-01 5.5841e+02 1.9813e+01 1.0116e+03 5.5841e+02 1.9813e+01 1.0116e+03 1.0788e-04 1.4097e-05 3.2929e-04 3.8354e-02 9.6165e-01 0.0000e+00 7.7004e-01 2.2996e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 9.4000e-01 1.2880e+06 5.5315e+02 4.3168e+01 9.8725e-07 4.8744e-01 3.9985e-01 1.1271e-01 5.5968e+02 1.8025e+01 1.0115e+03 5.5968e+02 1.8025e+01 1.0115e+03 1.0818e-04 1.3437e-05 3.2929e-04 2.7415e-02 9.7259e-01 0.0000e+00 7.1015e-01 2.8985e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 9.6000e-01 8.9200e+05 5.5315e+02 2.6004e+01 1.6952e-06 2.7229e-01 6.1500e-01 1.1271e-01 5.6094e+02 1.6244e+01 1.0113e+03 5.6094e+02 1.6244e+01 1.0113e+03 1.0845e-04 1.2477e-05 3.2929e-04 1.6340e-02 9.8366e-01 0.0000e+00 5.9920e-01 4.0080e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 9.8000e-01 4.9600e+05 5.5315e+02 1.2066e+01 2.1188e-06 8.8729e-01 0.0000e+00 1.1271e-01 1.0720e+01 1.0720e+01 1.0112e+03 1.0720e+01 1.0720e+01 1.0112e+03 1.1716e-05 1.1716e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.0000e+00 1.0000e+05 5.5315e+02 2.3385e+00 1.0097e-05 8.8729e-01 0.0000e+00 1.1271e-01 2.0755e+00 2.0755e+00 1.0110e+03 2.0755e+00 2.0755e+00 1.0110e+03 1.1560e-05 1.1560e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.0200e+00 4.9600e+05 5.8315e+02 1.1342e+01 2.0987e-06 8.8729e-01 0.0000e+00 1.1271e-01 1.0076e+01 1.0076e+01 1.0112e+03 1.0076e+01 1.0076e+01 1.0112e+03 1.2221e-05 1.2221e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.0400e+00 8.9200e+05 5.8315e+02 2.1089e+01 1.2070e-06 8.8729e-01 0.0000e+00 1.1271e-01 1.8756e+01 1.8756e+01 1.0113e+03 1.8756e+01 1.8756e+01 1.0113e+03 1.2405e-05 1.2405e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.0600e+00 1.2880e+06 5.8315e+02 3.2115e+01 1.2866e-06 4.3627e-02 8.4366e-01 1.1271e-01 5.1804e+02 2.7265e+01 1.0115e+03 5.1804e+02 2.7265e+01 1.0115e+03 8.2939e-05 1.2695e-05 3.2929e-04 2.4366e-02 9.7563e-01 0.0000e+00 5.1344e-01 4.8656e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.0800e+00 1.6840e+06 5.8315e+02 4.8218e+01 8.2999e-07 3.0186e-01 5.8543e-01 1.1271e-01 5.1649e+02 2.9209e+01 1.0116e+03 5.1649e+02 2.9209e+01 1.0116e+03 8.2756e-05 1.3409e-05 3.2929e-04 3.6932e-02 9.6307e-01 0.0000e+00 6.1026e-01 3.8974e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.1000e+00 2.0800e+06 5.8315e+02 6.3818e+01 6.0757e-07 4.2838e-01 4.5891e-01 1.1271e-01 5.1495e+02 3.1163e+01 1.0118e+03 5.1495e+02 3.1163e+01 1.0118e+03 8.2556e-05 1.3965e-05 3.2929e-04 4.9339e-02 9.5066e-01 0.0000e+00 6.7192e-01 3.2808e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.1200e+00 2.4760e+06 5.8315e+02 7.8934e+01 4.7605e-07 5.0379e-01 3.8350e-01 1.1271e-01 5.1339e+02 3.3128e+01 1.0120e+03 5.1339e+02 3.3128e+01 1.0120e+03 8.2339e-05 1.4414e-05 3.2929e-04 6.1589e-02 9.3841e-01 0.0000e+00 7.1454e-01 2.8546e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.1400e+00 2.8720e+06 5.8315e+02 9.3585e+01 3.8922e-07 5.5409e-01 3.3320e-01 1.1271e-01 5.1184e+02 3.5105e+01 1.0121e+03 5.1184e+02 3.5105e+01 1.0121e+03 8.2106e-05 1.4788e-05 3.2929e-04 7.3685e-02 9.2632e-01 0.0000e+00 7.4571e-01 2.5429e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.1600e+00 3.2680e+06 5.8315e+02 1.0779e+02 3.2766e-07 5.9019e-01 2.9710e-01 1.1271e-01 5.1028e+02 3.7093e+01 1.0123e+03 5.1028e+02 3.7093e+01 1.0123e+03 8.1860e-05 1.5107e-05 3.2929e-04 8.5630e-02 9.1437e-01 0.0000e+00 7.6944e-01 2.3056e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.1800e+00 3.6640e+06 5.8315e+02 1.2156e+02 2.8178e-07 6.1751e-01 2.6978e-01 1.1271e-01 5.0871e+02 3.9092e+01 1.0125e+03 5.0871e+02 3.9092e+01 1.0125e+03 8.1599e-05 1.5383e-05 3.2929e-04 9.7426e-02 9.0257e-01 0.0000e+00 7.8808e-01 2.1192e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.2000e+00 4.0600e+06 5.8315e+02 1.3492e+02 2.4628e-07 6.3902e-01 2.4827e-01 1.1271e-01 5.0714e+02 4.1103e+01 1.0126e+03 5.0714e+02 4.1103e+01 1.0126e+03 8.1325e-05 1.5628e-05 3.2929e-04 1.0908e-01 8.9092e-01 0.0000e+00 8.0306e-01 1.9694e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.2200e+00 4.4560e+06 5.8315e+02 1.4788e+02 2.1803e-07 6.5648e-01 2.3081e-01 1.1271e-01 5.0557e+02 4.3124e+01 1.0128e+03 5.0557e+02 4.3124e+01 1.0128e+03 8.1039e-05 1.5847e-05 3.2929e-04 1.2058e-01 8.7942e-01 0.0000e+00 8.1535e-01 1.8465e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.2400e+00 4.8520e+06 5.8315e+02 1.6046e+02 1.9502e-07 6.7102e-01 2.1627e-01 1.1271e-01 5.0399e+02 4.5158e+01 1.0130e+03 5.0399e+02 4.5158e+01 1.0130e+03 8.0742e-05 1.6047e-05 3.2929e-04 1.3195e-01 8.6805e-01 0.0000e+00 8.2557e-01 1.7443e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.2600e+00 5.2480e+06 5.8315e+02 1.7267e+02 1.7593e-07 6.8338e-01 2.0390e-01 1.1271e-01 5.0240e+02 4.7203e+01 1.0131e+03 5.0240e+02 4.7203e+01 1.0131e+03 8.0433e-05 1.6230e-05 3.2929e-04 1.4318e-01 8.5682e-01 0.0000e+00 8.3419e-01 1.6581e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.2800e+00 5.6440e+06 5.8315e+02 1.8453e+02 1.5985e-07 6.9409e-01 1.9320e-01 1.1271e-01 5.0081e+02 4.9259e+01 1.0133e+03 5.0081e+02 4.9259e+01 1.0133e+03 8.0115e-05 1.6401e-05 3.2929e-04 1.5427e-01 8.4573e-01 0.0000e+00 8.4154e-01 1.5846e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.3000e+00 6.0400e+06 5.8315e+02 1.9604e+02 1.4613e-07 7.0351e-01 1.8378e-01 1.1271e-01 4.9921e+02 5.1327e+01 1.0135e+03 4.9921e+02 5.1327e+01 1.0135e+03 7.9786e-05 1.6561e-05 3.2929e-04 1.6523e-01 8.3477e-01 0.0000e+00 8.4786e-01 1.5214e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.3200e+00 6.4360e+06 5.8315e+02 2.0722e+02 1.3430e-07 7.1191e-01 1.7538e-01 1.1271e-01 4.9761e+02 5.3407e+01 1.0136e+03 4.9761e+02 5.3407e+01 1.0136e+03 7.9448e-05 1.6713e-05 3.2929e-04 1.7606e-01 8.2394e-01 0.0000e+00 8.5333e-01 1.4667e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.3400e+00 6.8320e+06 5.8315e+02 2.1808e+02 1.2398e-07 7.1948e-01 1.6781e-01 1.1271e-01 4.9600e+02 5.5498e+01 1.0138e+03 4.9600e+02 5.5498e+01 1.0138e+03 7.9102e-05 1.6858e-05 3.2929e-04 1.8676e-01 8.1324e-01 0.0000e+00 8.5811e-01 1.4189e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.3600e+00 7.2280e+06 5.8315e+02 2.2864e+02 1.1493e-07 7.2640e-01 1.6089e-01 1.1271e-01 4.9439e+02 5.7601e+01 1.0140e+03 4.9439e+02 5.7601e+01 1.0140e+03 7.8748e-05 1.6997e-05 3.2929e-04 1.9733e-01 8.0267e-01 0.0000e+00 8.6229e-01 1.3771e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.3800e+00 7.6240e+06 5.8315e+02 2.3890e+02 1.0691e-07 7.3276e-01 1.5453e-01 1.1271e-01 4.9277e+02 5.9717e+01 1.0141e+03 4.9277e+02 5.9717e+01 1.0141e+03 7.8386e-05 1.7132e-05 3.2929e-04 2.0778e-01 7.9222e-01 0.0000e+00 8.6597e-01 1.3403e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.4000e+00 8.0200e+06 5.8315e+02 2.4887e+02 9.9776e-08 7.3868e-01 1.4861e-01 1.1271e-01 4.9114e+02 6.1844e+01 1.0143e+03 4.9114e+02 6.1844e+01 1.0143e+03 7.8016e-05 1.7263e-05 3.2929e-04 2.1811e-01 7.8189e-01 0.0000e+00 8.6923e-01 1.3077e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.4200e+00 8.4160e+06 5.8315e+02 2.5857e+02 9.3383e-08 7.4422e-01 1.4307e-01 1.1271e-01 4.8951e+02 6.3983e+01 1.0145e+03 4.8951e+02 6.3983e+01 1.0145e+03 7.7640e-05 1.7391e-05 3.2929e-04 2.2831e-01 7.7169e-01 0.0000e+00 8.7211e-01 1.2789e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.4400e+00 8.8120e+06 5.8315e+02 2.6800e+02 8.7626e-08 7.4946e-01 1.3783e-01 1.1271e-01 4.8787e+02 6.6135e+01 1.0146e+03 4.8787e+02 6.6135e+01 1.0146e+03 7.7258e-05 1.7517e-05 3.2929e-04 2.3840e-01 7.6160e-01 0.0000e+00 8.7467e-01 1.2533e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.4600e+00 9.2080e+06 5.8315e+02 2.7717e+02 8.2418e-08 7.5444e-01 1.3285e-01 1.1271e-01 4.8623e+02 6.8299e+01 1.0148e+03 4.8623e+02 6.8299e+01 1.0148e+03 7.6869e-05 1.7641e-05 3.2929e-04 2.4838e-01 7.5162e-01 0.0000e+00 8.7695e-01 1.2305e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.4800e+00 9.6040e+06 5.8315e+02 2.8609e+02 7.7686e-08 7.5920e-01 1.2809e-01 1.1271e-01 4.8457e+02 7.0476e+01 1.0150e+03 4.8457e+02 7.0476e+01 1.0150e+03 7.6475e-05 1.7765e-05 3.2929e-04 2.5824e-01 7.4176e-01 0.0000e+00 8.7898e-01 1.2102e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.5000e+00 1.0000e+07 5.8315e+02 2.9478e+02 7.3370e-08 7.6378e-01 1.2351e-01 1.1271e-01 4.8291e+02 7.2665e+01 1.0151e+03 4.8291e+02 7.2665e+01 1.0151e+03 7.6075e-05 1.7888e-05 3.2929e-04 2.6799e-01 7.3201e-01 0.0000e+00 8.8078e-01 1.1922e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.5200e+00 1.1000e+07 5.8315e+02 3.1568e+02 6.4004e-08 7.7474e-01 1.1254e-01 1.1271e-01 4.7869e+02 7.8250e+01 1.0156e+03 4.7869e+02 7.8250e+01 1.0156e+03 7.5043e-05 1.8197e-05 3.2929e-04 2.9214e-01 7.0786e-01 0.0000e+00 8.8451e-01 1.1549e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.5400e+00 1.2000e+07 5.8315e+02 3.3522e+02 5.6368e-08 7.8515e-01 1.0214e-01 1.1271e-01 4.7441e+02 8.3920e+01 1.0160e+03 4.7441e+02 8.3920e+01 1.0160e+03 7.3984e-05 1.8510e-05 3.2929e-04 3.1562e-01 6.8438e-01 0.0000e+00 8.8727e-01 1.1273e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.5600e+00 1.3000e+07 5.8315e+02 3.5351e+02 5.0041e-08 7.9527e-01 9.2016e-02 1.1271e-01 4.7007e+02 8.9678e+01 1.0164e+03 4.7007e+02 8.9678e+01 1.0164e+03 7.2901e-05 1.8830e-05 3.2929e-04 3.3847e-01 6.6153e-01 0.0000e+00 8.8925e-01 1.1075e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.5800e+00 1.4000e+07 5.8315e+02 3.7064e+02 4.4727e-08 8.0535e-01 8.1944e-02 1.1271e-01 4.6568e+02 9.5527e+01 1.0168e+03 4.6568e+02 9.5527e+01 1.0168e+03 7.1797e-05 1.9161e-05 3.2929e-04 3.6073e-01 6.3927e-01 0.0000e+00 8.9060e-01 1.0940e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.6000e+00 1.5000e+07 5.8315e+02 3.8669e+02 4.0213e-08 8.1555e-01 7.1735e-02 1.1271e-01 4.6121e+02 1.0147e+02 1.0173e+03 4.6121e+02 1.0147e+02 1.0173e+03 7.0674e-05 1.9505e-05 3.2929e-04 3.8242e-01 6.1758e-01 0.0000e+00 8.9143e-01 1.0857e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.6200e+00 1.6000e+07 5.8315e+02 4.0176e+02 3.6339e-08 8.2607e-01 6.1222e-02 1.1271e-01 4.5668e+02 1.0752e+02 1.0177e+03 4.5668e+02 1.0752e+02 1.0177e+03 6.9535e-05 1.9866e-05 3.2929e-04 4.0358e-01 5.9642e-01 0.0000e+00 8.9180e-01 1.0820e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.6400e+00 1.7000e+07 5.8315e+02 4.1592e+02 3.2986e-08 8.3705e-01 5.0240e-02 1.1271e-01 4.5206e+02 1.1367e+02 1.0181e+03 4.5206e+02 1.1367e+02 1.0181e+03 6.8382e-05 2.0245e-05 3.2929e-04 4.2423e-01 5.7577e-01 0.0000e+00 8.9179e-01 1.0821e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.6600e+00 1.8000e+07 5.8315e+02 4.2922e+02 3.0062e-08 8.4867e-01 3.8624e-02 1.1271e-01 4.4735e+02 1.1994e+02 1.0185e+03 4.4735e+02 1.1994e+02 1.0185e+03 6.7214e-05 2.0645e-05 3.2929e-04 4.4441e-01 5.5559e-01 0.0000e+00 8.9142e-01 1.0858e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.6800e+00 1.9000e+07 5.8315e+02 4.4174e+02 2.7496e-08 8.6110e-01 2.6192e-02 1.1271e-01 4.4254e+02 1.2633e+02 1.0189e+03 4.4254e+02 1.2633e+02 1.0189e+03 6.6034e-05 2.1068e-05 3.2929e-04 4.6414e-01 5.3586e-01 0.0000e+00 8.9072e-01 1.0928e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.7000e+00 2.0000e+07 5.8315e+02 4.5353e+02 2.5230e-08 8.7455e-01 1.2742e-02 1.1271e-01 4.3761e+02 1.3286e+02 1.0194e+03 4.3761e+02 1.3286e+02 1.0194e+03 6.4840e-05 2.1517e-05 3.2929e-04 4.8347e-01 5.1653e-01 0.0000e+00 8.8972e-01 1.1028e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.7200e+00 2.1000e+07 5.8315e+02 4.6414e+02 1.4880e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.3410e+02 4.3410e+02 1.0198e+03 4.3410e+02 4.3410e+02 1.0198e+03 6.4038e-05 6.4038e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.7400e+00 2.2000e+07 5.8315e+02 4.7084e+02 1.3791e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.4069e+02 4.4069e+02 1.0202e+03 4.4069e+02 4.4069e+02 1.0202e+03 6.5972e-05 6.5972e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.7600e+00 2.3000e+07 5.8315e+02 4.7714e+02 1.2834e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.4691e+02 4.4691e+02 1.0206e+03 4.4691e+02 4.4691e+02 1.0206e+03 6.7891e-05 6.7891e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.7800e+00 2.4000e+07 5.8315e+02 4.8310e+02 1.1989e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.5280e+02 4.5280e+02 1.0211e+03 4.5280e+02 4.5280e+02 1.0211e+03 6.9797e-05 6.9797e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.8000e+00 2.5000e+07 5.8315e+02 4.8874e+02 1.1236e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.5837e+02 4.5837e+02 1.0215e+03 4.5837e+02 4.5837e+02 1.0215e+03 7.1695e-05 7.1695e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.8200e+00 2.6000e+07 5.8315e+02 4.9409e+02 1.0563e-08 8.8729e-01 0.0000e+00 1.1271e-01 4.6367e+02 4.6367e+02 1.0219e+03 4.6367e+02 4.6367e+02 1.0219e+03 7.3587e-05 7.3587e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.8400e+00 2.7000e+07 5.8315e+02 4.9918e+02 9.9572e-09 8.8729e-01 0.0000e+00 1.1271e-01 4.6872e+02 4.6872e+02 1.0223e+03 4.6872e+02 4.6872e+02 1.0223e+03 7.5475e-05 7.5475e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.8600e+00 2.8000e+07 5.8315e+02 5.0404e+02 9.4099e-09 8.8729e-01 0.0000e+00 1.1271e-01 4.7353e+02 4.7353e+02 1.0228e+03 4.7353e+02 4.7353e+02 1.0228e+03 7.7360e-05 7.7360e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.8800e+00 2.9000e+07 5.8315e+02 5.0868e+02 8.9131e-09 8.8729e-01 0.0000e+00 1.1271e-01 4.7814e+02 4.7814e+02 1.0232e+03 4.7814e+02 4.7814e+02 1.0232e+03 7.9245e-05 7.9245e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.9000e+00 3.0000e+07 5.8315e+02 5.1311e+02 8.4604e-09 8.8729e-01 0.0000e+00 1.1271e-01 4.8254e+02 4.8254e+02 1.0236e+03 4.8254e+02 4.8254e+02 1.0236e+03 8.1131e-05 8.1131e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.9200e+00 3.1000e+07 5.8315e+02 5.1736e+02 8.0464e-09 8.8729e-01 0.0000e+00 1.1271e-01 4.8677e+02 4.8677e+02 1.0240e+03 4.8677e+02 4.8677e+02 1.0240e+03 8.3018e-05 8.3018e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.9400e+00 3.2000e+07 5.8315e+02 5.2144e+02 7.6664e-09 8.8729e-01 0.0000e+00 1.1271e-01 4.9083e+02 4.9083e+02 1.0245e+03 4.9083e+02 4.9083e+02 1.0245e+03 8.4907e-05 8.4907e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.9600e+00 3.3000e+07 5.8315e+02 5.2536e+02 7.3166e-09 8.8729e-01 0.0000e+00 1.1271e-01 4.9473e+02 4.9473e+02 1.0249e+03 4.9473e+02 4.9473e+02 1.0249e+03 8.6800e-05 8.6800e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.9800e+00 3.4000e+07 5.8315e+02 5.2913e+02 6.9937e-09 8.8729e-01 0.0000e+00 1.1271e-01 4.9849e+02 4.9849e+02 1.0253e+03 4.9849e+02 4.9849e+02 1.0253e+03 8.8696e-05 8.8696e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 2.0000e+00 3.5000e+07 5.8315e+02 5.3277e+02 6.6947e-09 8.8729e-01 0.0000e+00 1.1271e-01 5.0211e+02 5.0211e+02 1.0257e+03 5.0211e+02 5.0211e+02 1.0257e+03 9.0597e-05 9.0597e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 From 3f99c008dfac7d7625ec5c3675006d9f2051c177 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Tue, 29 Jul 2025 11:34:51 -0500 Subject: [PATCH 12/28] Use full names --- .../CompositionalMultiphaseFluidUpdates.hpp | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp index 8950139880a..6af1f3366dc 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp @@ -49,13 +49,13 @@ class CompositionalMultiphaseFluidUpdates final : public MultiFluidBase::KernelW arrayView1d< integer const > const & phaseOrder, arrayView1d< real64 const > const & componentMolarWeight, bool const useMass, - MultiFluidBase::PhaseProp::ViewType phaseFrac, - MultiFluidBase::PhaseProp::ViewType phaseDens, + MultiFluidBase::PhaseProp::ViewType phaseFraction, + MultiFluidBase::PhaseProp::ViewType phaseDensity, MultiFluidBase::PhaseProp::ViewType phaseMassDensity, - MultiFluidBase::PhaseProp::ViewType phaseVisc, + MultiFluidBase::PhaseProp::ViewType phaseViscosity, MultiFluidBase::PhaseProp::ViewType phaseEnthalpy, MultiFluidBase::PhaseProp::ViewType phaseInternalEnergy, - MultiFluidBase::PhaseComp::ViewType phaseCompFrac, + MultiFluidBase::PhaseComp::ViewType phaseComponentFraction, MultiFluidBase::FluidProp::ViewType totalDensity, MultiFluidBase::PhaseComp::ViewValueType kValues ); @@ -63,13 +63,13 @@ class CompositionalMultiphaseFluidUpdates final : public MultiFluidBase::KernelW virtual void compute( real64 const pressure, real64 const temperature, arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition, - MultiFluidBase::PhaseProp::SliceType const phaseFrac, - MultiFluidBase::PhaseProp::SliceType const phaseDens, + MultiFluidBase::PhaseProp::SliceType const phaseFraction, + MultiFluidBase::PhaseProp::SliceType const phaseDensity, MultiFluidBase::PhaseProp::SliceType const phaseMassDensity, - MultiFluidBase::PhaseProp::SliceType const phaseVisc, + MultiFluidBase::PhaseProp::SliceType const phaseViscosity, MultiFluidBase::PhaseProp::SliceType const phaseEnthalpy, MultiFluidBase::PhaseProp::SliceType const phaseInternalEnergy, - MultiFluidBase::PhaseComp::SliceType const phaseCompFrac, + MultiFluidBase::PhaseComp::SliceType const phaseComponentFraction, MultiFluidBase::FluidProp::SliceType const totalDensity ) const override; GEOS_HOST_DEVICE @@ -84,13 +84,13 @@ class CompositionalMultiphaseFluidUpdates final : public MultiFluidBase::KernelW void compute( real64 const pressure, real64 const temperature, arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition, - MultiFluidBase::PhaseProp::SliceType const phaseFrac, - MultiFluidBase::PhaseProp::SliceType const phaseDens, + MultiFluidBase::PhaseProp::SliceType const phaseFraction, + MultiFluidBase::PhaseProp::SliceType const phaseDensity, MultiFluidBase::PhaseProp::SliceType const phaseMassDensity, - MultiFluidBase::PhaseProp::SliceType const phaseVisc, + MultiFluidBase::PhaseProp::SliceType const phaseViscosity, MultiFluidBase::PhaseProp::SliceType const phaseEnthalpy, MultiFluidBase::PhaseProp::SliceType const phaseInternalEnergy, - MultiFluidBase::PhaseComp::SliceType const phaseCompFrac, + MultiFluidBase::PhaseComp::SliceType const phaseComponentFraction, MultiFluidBase::FluidProp::SliceType const totalDensity, MultiFluidBase::PhaseComp::SliceType::ValueType const & kValues ) const; @@ -145,24 +145,24 @@ CompositionalMultiphaseFluidUpdates( compositional::ComponentProperties const & arrayView1d< integer const > const & phaseOrder, arrayView1d< real64 const > const & componentMolarWeight, bool const useMass, - MultiFluidBase::PhaseProp::ViewType phaseFrac, - MultiFluidBase::PhaseProp::ViewType phaseDens, + MultiFluidBase::PhaseProp::ViewType phaseFraction, + MultiFluidBase::PhaseProp::ViewType phaseDensity, MultiFluidBase::PhaseProp::ViewType phaseMassDensity, - MultiFluidBase::PhaseProp::ViewType phaseVisc, + MultiFluidBase::PhaseProp::ViewType phaseViscosity, MultiFluidBase::PhaseProp::ViewType phaseEnthalpy, MultiFluidBase::PhaseProp::ViewType phaseInternalEnergy, - MultiFluidBase::PhaseComp::ViewType phaseCompFrac, + MultiFluidBase::PhaseComp::ViewType phaseComponentFraction, MultiFluidBase::FluidProp::ViewType totalDensity, MultiFluidBase::PhaseComp::ViewValueType kValues ): MultiFluidBase::KernelWrapper( componentMolarWeight, useMass, - std::move( phaseFrac ), - std::move( phaseDens ), + std::move( phaseFraction ), + std::move( phaseDensity ), std::move( phaseMassDensity ), - std::move( phaseVisc ), + std::move( phaseViscosity ), std::move( phaseEnthalpy ), std::move( phaseInternalEnergy ), - std::move( phaseCompFrac ), + std::move( phaseComponentFraction ), std::move( totalDensity ) ), m_componentProperties( componentProperties.createKernelWrapper() ), m_flash( flash.createKernelWrapper() ), @@ -181,13 +181,13 @@ CompositionalMultiphaseFluidUpdates< FLASH, PHASE1, PHASE2, PHASE3 >::compute( real64 const pressure, real64 const temperature, arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition, - MultiFluidBase::PhaseProp::SliceType const phaseFrac, - MultiFluidBase::PhaseProp::SliceType const phaseDens, + MultiFluidBase::PhaseProp::SliceType const phaseFraction, + MultiFluidBase::PhaseProp::SliceType const phaseDensity, MultiFluidBase::PhaseProp::SliceType const phaseMassDensity, - MultiFluidBase::PhaseProp::SliceType const phaseVisc, + MultiFluidBase::PhaseProp::SliceType const phaseViscosity, MultiFluidBase::PhaseProp::SliceType const phaseEnthalpy, MultiFluidBase::PhaseProp::SliceType const phaseInternalEnergy, - MultiFluidBase::PhaseComp::SliceType const phaseCompFrac, + MultiFluidBase::PhaseComp::SliceType const phaseComponentFraction, MultiFluidBase::FluidProp::SliceType const totalDensity ) const { integer constexpr maxNumComp = MultiFluidBase::MAX_NUM_COMPONENTS; @@ -199,13 +199,13 @@ CompositionalMultiphaseFluidUpdates< FLASH, PHASE1, PHASE2, PHASE3 >::compute( compute( pressure, temperature, composition, - phaseFrac, - phaseDens, + phaseFraction, + phaseDensity, phaseMassDensity, - phaseVisc, + phaseViscosity, phaseEnthalpy, phaseInternalEnergy, - phaseCompFrac, + phaseComponentFraction, totalDensity, kValues[0][0] ); } @@ -218,13 +218,13 @@ CompositionalMultiphaseFluidUpdates< FLASH, PHASE1, PHASE2, PHASE3 >::compute( real64 const pressure, real64 const temperature, arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition, - MultiFluidBase::PhaseProp::SliceType const phaseFrac, - MultiFluidBase::PhaseProp::SliceType const phaseDens, + MultiFluidBase::PhaseProp::SliceType const phaseFraction, + MultiFluidBase::PhaseProp::SliceType const phaseDensity, MultiFluidBase::PhaseProp::SliceType const phaseMassDensity, - MultiFluidBase::PhaseProp::SliceType const phaseVisc, + MultiFluidBase::PhaseProp::SliceType const phaseViscosity, MultiFluidBase::PhaseProp::SliceType const phaseEnthalpy, MultiFluidBase::PhaseProp::SliceType const phaseInternalEnergy, - MultiFluidBase::PhaseComp::SliceType const phaseCompFrac, + MultiFluidBase::PhaseComp::SliceType const phaseComponentFraction, MultiFluidBase::FluidProp::SliceType const totalDensity, MultiFluidBase::PhaseComp::SliceType::ValueType const & kValues ) const { @@ -261,25 +261,25 @@ CompositionalMultiphaseFluidUpdates< FLASH, PHASE1, PHASE2, PHASE3 >::compute( temperature, compMoleFrac.toSliceConst(), kValues, - phaseFrac, - phaseCompFrac ); + phaseFraction, + phaseComponentFraction ); // 3. Calculate the phase densities m_phase1.density.compute( m_componentProperties, pressure, temperature, - phaseCompFrac.value[m_phaseOrder[0]].toSliceConst(), - phaseDens.value[m_phaseOrder[0]], - phaseDens.derivs[m_phaseOrder[0]], + phaseComponentFraction.value[m_phaseOrder[0]].toSliceConst(), + phaseDensity.value[m_phaseOrder[0]], + phaseDensity.derivs[m_phaseOrder[0]], phaseMassDensity.value[m_phaseOrder[0]], phaseMassDensity.derivs[m_phaseOrder[0]], m_useMass ); m_phase2.density.compute( m_componentProperties, pressure, temperature, - phaseCompFrac.value[m_phaseOrder[1]].toSliceConst(), - phaseDens.value[m_phaseOrder[1]], - phaseDens.derivs[m_phaseOrder[1]], + phaseComponentFraction.value[m_phaseOrder[1]].toSliceConst(), + phaseDensity.value[m_phaseOrder[1]], + phaseDensity.derivs[m_phaseOrder[1]], phaseMassDensity.value[m_phaseOrder[1]], phaseMassDensity.derivs[m_phaseOrder[1]], m_useMass ); @@ -288,9 +288,9 @@ CompositionalMultiphaseFluidUpdates< FLASH, PHASE1, PHASE2, PHASE3 >::compute( m_phase3.density.compute( m_componentProperties, pressure, temperature, - phaseCompFrac.value[m_phaseOrder[2]].toSliceConst(), - phaseDens.value[m_phaseOrder[2]], - phaseDens.derivs[m_phaseOrder[2]], + phaseComponentFraction.value[m_phaseOrder[2]].toSliceConst(), + phaseDensity.value[m_phaseOrder[2]], + phaseDensity.derivs[m_phaseOrder[2]], phaseMassDensity.value[m_phaseOrder[2]], phaseMassDensity.derivs[m_phaseOrder[2]], m_useMass ); @@ -300,31 +300,31 @@ CompositionalMultiphaseFluidUpdates< FLASH, PHASE1, PHASE2, PHASE3 >::compute( m_phase1.viscosity.compute( m_componentProperties, pressure, temperature, - phaseCompFrac.value[m_phaseOrder[0]].toSliceConst(), + phaseComponentFraction.value[m_phaseOrder[0]].toSliceConst(), phaseMassDensity.value[m_phaseOrder[0]], phaseMassDensity.derivs[m_phaseOrder[0]].toSliceConst(), - phaseVisc.value[m_phaseOrder[0]], - phaseVisc.derivs[m_phaseOrder[0]], + phaseViscosity.value[m_phaseOrder[0]], + phaseViscosity.derivs[m_phaseOrder[0]], m_useMass ); m_phase2.viscosity.compute( m_componentProperties, pressure, temperature, - phaseCompFrac.value[m_phaseOrder[1]].toSliceConst(), + phaseComponentFraction.value[m_phaseOrder[1]].toSliceConst(), phaseMassDensity.value[m_phaseOrder[1]], phaseMassDensity.derivs[m_phaseOrder[1]].toSliceConst(), - phaseVisc.value[m_phaseOrder[1]], - phaseVisc.derivs[m_phaseOrder[1]], + phaseViscosity.value[m_phaseOrder[1]], + phaseViscosity.derivs[m_phaseOrder[1]], m_useMass ); if constexpr (2 < FLASH::KernelWrapper::getNumberOfPhases()) { m_phase3.viscosity.compute( m_componentProperties, pressure, temperature, - phaseCompFrac.value[m_phaseOrder[2]].toSliceConst(), + phaseComponentFraction.value[m_phaseOrder[2]].toSliceConst(), phaseMassDensity.value[m_phaseOrder[2]], phaseMassDensity.derivs[m_phaseOrder[2]].toSliceConst(), - phaseVisc.value[m_phaseOrder[2]], - phaseVisc.derivs[m_phaseOrder[2]], + phaseViscosity.value[m_phaseOrder[2]], + phaseViscosity.derivs[m_phaseOrder[2]], m_useMass ); } @@ -333,16 +333,16 @@ CompositionalMultiphaseFluidUpdates< FLASH, PHASE1, PHASE2, PHASE3 >::compute( for( integer ip = 0; ip < FLASH::KernelWrapper::getNumberOfPhases(); ++ip ) { convertDerivativesToTotalMoleFraction( numComp, - phaseCompFrac.derivs[ip].toSliceConst(), - phaseDens.derivs[ip], + phaseComponentFraction.derivs[ip].toSliceConst(), + phaseDensity.derivs[ip], workSpace ); convertDerivativesToTotalMoleFraction( numComp, - phaseCompFrac.derivs[ip].toSliceConst(), + phaseComponentFraction.derivs[ip].toSliceConst(), phaseMassDensity.derivs[ip], workSpace ); convertDerivativesToTotalMoleFraction( numComp, - phaseCompFrac.derivs[ip].toSliceConst(), - phaseVisc.derivs[ip], + phaseComponentFraction.derivs[ip].toSliceConst(), + phaseViscosity.derivs[ip], workSpace ); } @@ -356,8 +356,8 @@ CompositionalMultiphaseFluidUpdates< FLASH, PHASE1, PHASE2, PHASE3 >::compute( for( integer ip = 0; ip < numPhase; ++ip ) { - auto const & phaseComposition = phaseCompFrac.value[ip].toSliceConst(); - auto const & dPhaseComposition = phaseCompFrac.derivs[ip].toSliceConst(); + auto const & phaseComposition = phaseComponentFraction.value[ip].toSliceConst(); + auto const & dPhaseComposition = phaseComponentFraction.derivs[ip].toSliceConst(); for( integer ic = 0; ic < numComp; ++ic ) { @@ -372,28 +372,28 @@ CompositionalMultiphaseFluidUpdates< FLASH, PHASE1, PHASE2, PHASE3 >::compute( convertToMassFractions( dCompMoleFrac_dCompMassFrac, phaseMolecularWeight, dPhaseMolecularWeight, - phaseFrac, - phaseCompFrac, + phaseFraction, + phaseComponentFraction, phaseMassDensity.derivs, - phaseVisc.derivs, + phaseViscosity.derivs, phaseEnthalpy.derivs, phaseInternalEnergy.derivs ); // Molar density equals mass density for( integer ip = 0; ip < numPhase; ++ip ) { - phaseDens.value[ip] = phaseMassDensity.value[ip]; + phaseDensity.value[ip] = phaseMassDensity.value[ip]; for( integer idof = 0; idof < numDof; ++idof ) { - phaseDens.derivs( ip, idof ) = phaseMassDensity.derivs( ip, idof ); + phaseDensity.derivs( ip, idof ) = phaseMassDensity.derivs( ip, idof ); } } } // 7. Compute total fluid mass/molar density and derivatives - computeTotalDensity( phaseFrac, - phaseDens, + computeTotalDensity( phaseFraction, + phaseDensity, totalDensity ); } From 6a2a742cbf47f85ac75d68a1a6263694702e62ac Mon Sep 17 00:00:00 2001 From: dkachuma Date: Tue, 29 Jul 2025 11:40:37 -0500 Subject: [PATCH 13/28] Some tests --- .../functions/NegativeTwoPhaseFlash_impl.hpp | 34 +++++++------------ .../parameters/FlashParameters.cpp | 1 + .../parameters/FlashParameters.hpp | 9 +++-- .../unitTests/TestFluidUtilities.hpp | 9 +++++ .../testImmiscibleWaterFlashModel.cpp | 2 +- .../testNegativeTwoPhaseFlash9Comp.cpp | 24 ++++++++----- .../unitTests/testStabilityTest2Comp.cpp | 4 +-- .../unitTests/testStabilityTest9Comp.cpp | 16 ++++----- 8 files changed, 55 insertions(+), 44 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index 6e3ff35613f..47ac61ea5c0 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -137,25 +137,6 @@ void NegativeTwoPhaseFlash::computeDerivatives( LvArray::forValuesInSlice( liquidCompositionDerivs, setZero ); LvArray::forValuesInSlice( vapourCompositionDerivs, setZero ); - // Check if we are single or 2-phase - if( false && vapourFraction < MultiFluidConstants::epsilon ) - { - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidCompositionDerivs( ic, Deriv::dC + ic ) = 1.0; - vapourCompositionDerivs( ic, Deriv::dC + ic ) = 1.0; - } - } - else if( false && 1.0 - vapourFraction < MultiFluidConstants::epsilon ) - { - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidCompositionDerivs( ic, Deriv::dC + ic ) = 1.0; - vapourCompositionDerivs( ic, Deriv::dC + ic ) = 1.0; - } - } - else - { // Calculate the liquid and vapour fugacities and derivatives StackArray< real64, 2, 2*maxNumComps > logFugacity( 2, numComps ); StackArray< real64, 3, 2*maxNumComps * maxNumDofs > logFugacityDerivs( 2, numComps, numDofs ); @@ -221,7 +202,6 @@ void NegativeTwoPhaseFlash::computeDerivatives( liquidCompositionDerivs, vapourCompositionDerivs ); LvArray::forValuesInSlice( vapourFractionDerivs, []( real64 & v ){ v *= -1.0; } ); - } } } @@ -252,7 +232,7 @@ void NegativeTwoPhaseFlash::computeDerivatives( real64 const VL = phase1Fraction; real64 const factor1 = VL / (1.0 - VL); real64 const factor2 = 1.0 / (1.0 - VL); - + real64 sumDiffxy = 0.0; for( integer i = 0; i < numComps; ++i ) { real64 const phi_2_i = phase2Fugacity[i]; @@ -261,6 +241,8 @@ void NegativeTwoPhaseFlash::computeDerivatives( real64 const xi = phase2Composition[i]; real64 const yi = phase1Composition[i]; +sumDiffxy *= ((xi-yi)*(xi-yi)); + real64 col_N = 0.0; for( integer j = 0; j < numComps; ++j ) { @@ -284,6 +266,16 @@ void NegativeTwoPhaseFlash::computeDerivatives( } A( numComps, numComps ) = 0.0; + // Check for single phase trivial solution + if (sumDiffxy < MultiFluidConstants::fugacityTolerance) + { + for( integer i = 0; i < numComps; ++i ) + { + A( numComps, i ) = 0.0; + } + A( numComps, numComps ) = 1.0; + } + // Pressure and temperature derivatives for( integer ic = 0; ic < numComps; ++ic ) { diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp index c6e9159800e..941f28a950b 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp @@ -39,6 +39,7 @@ FlashParameters::FlashParameters( std::unique_ptr< ModelParameters > parameters m_continuousParameters[STABILITY_THRESHOLD] = -1.0e-8; m_continuousParameters[STABILITY_TOLERANCE] = 1.0e-8; m_continuousParameters[FLASH_TOLERANCE] = 1.0e-8; + m_continuousParameters[NEGATIVE_FLASH_TOLERANCE] = -1.0e-1; m_discreteParameters[STABILITY_MAX_ITERATIONS] = 300; m_discreteParameters[FLASH_MAX_ITERATIONS] = 300; diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp index 5e51237c642..fe430d83bbc 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp @@ -54,14 +54,17 @@ class FlashParameters : public ModelParameters /** The tolerance to use to determine convergece of the flash. */ static integer constexpr FLASH_TOLERANCE = 0; + /** The limit for negative flash tolerance. */ + static integer constexpr NEGATIVE_FLASH_TOLERANCE = 1; + /** The value of the tangent plane distance below which a mixture is determined to be unstable. */ - static integer constexpr STABILITY_THRESHOLD = 1; + static integer constexpr STABILITY_THRESHOLD = 2; /** The tolerance to use to determine convergece to a stationary point in the stability test. */ - static integer constexpr STABILITY_TOLERANCE = 2; + static integer constexpr STABILITY_TOLERANCE = 3; /* Number of continuous variables */ - static integer constexpr NUM_FLOAT = 3; + static integer constexpr NUM_FLOAT = 4; public: FlashParameters( std::unique_ptr< ModelParameters > parameters ); diff --git a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp index 80aae8c1932..bacaeb111be 100644 --- a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp +++ b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp @@ -110,7 +110,16 @@ void testNumericalDerivative( real64 const x, } checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, GEOS_FMT( "Numerical derivative for component {}", i ) ); +std::cout +<< std::setw(2) << i << " " +<< std::scientific << std::setprecision(5) << std::setw(12) << derivatives[i] << " " +<< std::scientific << std::setprecision(5) << std::setw(12) << selectedDerivative << " | " +<< std::scientific << std::setprecision(5) << std::setw(12) << leftValues[i] << " " << centreValues[i] << " " << rightValues[i] << " | " +<< std::scientific << std::setprecision(5) << std::setw(12) << derivatives[i]-selectedDerivative << " " +<< (relTolerance+absTolerance) << " " +<< "\n"; } +std::cout << "-------------------------------------------------\n"; } /** diff --git a/src/coreComponents/constitutive/unitTests/testImmiscibleWaterFlashModel.cpp b/src/coreComponents/constitutive/unitTests/testImmiscibleWaterFlashModel.cpp index 3387eb8495f..6ecc3545c18 100644 --- a/src/coreComponents/constitutive/unitTests/testImmiscibleWaterFlashModel.cpp +++ b/src/coreComponents/constitutive/unitTests/testImmiscibleWaterFlashModel.cpp @@ -105,7 +105,7 @@ class ImmiscibleWaterFlashModelTestFixture : public ::testing::TestWithParam< F equationOfState->m_equationsOfStateNames.emplace_back( eosName ); auto * criticalVolume = const_cast< CriticalVolume * >(m_parameters->get< CriticalVolume >()); - TestFluid< NC >::populateArray( criticalVolume->m_componentCriticalVolume, this->m_fluid->criticalVolume ); + TestFluid< NC >::createArray( criticalVolume->m_componentCriticalVolume, this->m_fluid->criticalVolume ); m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::VAPOUR)); diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp index bd751e0fac9..2d29639d437 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp @@ -223,6 +223,11 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< liquidComposition.toSlice(), vapourComposition.toSlice() ); + if (vapourFraction < 1.0e-7 || 1.0 - vapourFraction < 1.0e-7) + { + return; + } + NegativeTwoPhaseFlash::computeDerivatives( numComps, pressure, @@ -239,6 +244,7 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< // Test against numerically calculated values // --- Pressure derivatives --- +/** concatDerivatives( Deriv::dP, derivatives, vapourFractionDerivs, liquidCompositionDerivs, vapourCompositionDerivs ); real64 const dp = 1.0e-4 * pressure; geos::testing::internal::testNumericalDerivative< numValues >( @@ -246,7 +252,7 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< [&]( real64 const p, auto & values ) { evaluateFlash( p, temperature, composition, values ); } ); - +*/ // --- Temperature derivatives --- concatDerivatives( Deriv::dT, derivatives, vapourFractionDerivs, liquidCompositionDerivs, vapourCompositionDerivs ); real64 const dT = 1.0e-6 * temperature; @@ -255,7 +261,7 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< [&]( real64 const t, auto & values ) { evaluateFlash( pressure, t, composition, values ); } ); - +/** // --- Composition derivatives --- real64 constexpr dz = 1.0e-7; for( integer jc = 0; jc < numComps; ++jc ) @@ -271,7 +277,7 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< evaluateFlash( pressure, temperature, composition, values ); composition[jc] = originalFraction; }, 10*relTol, 10*absTol ); - } + }*/ } protected: @@ -309,7 +315,7 @@ using SoaveRedlichKwong = NegativeTwoPhaseFlashTest9CompFixture< EquationOfState TEST_P( PengRobinson, testNegativeFlash ) { - testFlash( GetParam() ); + //testFlash( GetParam() ); } TEST_P( PengRobinson, testNegativeFlashDerivatives ) @@ -319,12 +325,12 @@ TEST_P( PengRobinson, testNegativeFlashDerivatives ) TEST_P( SoaveRedlichKwong, testNegativeFlash ) { - testFlash( GetParam() ); + //testFlash( GetParam() ); } TEST_P( SoaveRedlichKwong, testNegativeFlashDerivatives ) { - testFlashDerivatives( GetParam() ); + //testFlashDerivatives( GetParam() ); } //------------------------------------------------------------------------------- @@ -457,14 +463,14 @@ INSTANTIATE_TEST_SUITE_P( FlashData( 8.000000e+07, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), FlashData( 1.000000e+08, 8.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), FlashData( 1.000000e+08, 8.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), - FlashData( 1.000000e+08, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ) + FlashData( 1.000000e+08, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ) ) ); INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlash, SoaveRedlichKwong, ::testing::Values( - FlashData( 1.000000e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000197, {0.000361, 0.839175}, {0.010852, 0.000016} ), + FlashData( 1.000000e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000197, {0.000361, 0.839175}, {0.010852, 0.000016} )/**, FlashData( 1.000000e+05, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.798097, {0.000372, 0.837963}, {0.011183, 0.000016} ), FlashData( 1.000000e+05, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998678, {0.000233, 0.937435}, {0.007035, 0.000017} ), FlashData( 1.013250e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000102, {0.000362, 0.839096}, {0.010741, 0.000015} ), @@ -568,7 +574,7 @@ INSTANTIATE_TEST_SUITE_P( FlashData( 1.500000e+07, 5.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.986509, {0.007097, 0.343039}, {0.009026, 0.166823} ), FlashData( 1.000000e+08, 8.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), FlashData( 1.000000e+08, 8.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), - FlashData( 1.000000e+08, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ) + FlashData( 1.000000e+08, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ) */ ) ); diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp index d5bbbbda39e..145deb9d82a 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp @@ -132,7 +132,7 @@ INSTANTIATE_TEST_SUITE_P(StabilityTest, PengRobinson, ::testing::ValuesIn({ {1.0e+06, 297.15, 0.400, -2.7755576e-16}, {1.0e+06, 353.15, 0.400, -1.1102230e-16}, - {5.0e+06, 297.15, 0.400, -1.8699196e-01}, + {5.0e+06, 297.15, 0.400, -1.8937164e-01}, {5.0e+06, 353.15, 0.400, 1.6653345e-16}, {2.0e+07, 297.15, 0.400, -1.2767565e-15}, {2.0e+07, 353.15, 0.400, -1.6653345e-16} @@ -144,7 +144,7 @@ INSTANTIATE_TEST_SUITE_P( ::testing::ValuesIn({ {1.0e+06, 297.15, 0.350, -2.7755576e-16}, {1.0e+06, 353.15, 0.350, -3.8857806e-16}, - {5.0e+06, 297.15, 0.350, -2.0115518e-01}, + {5.0e+06, 297.15, 0.350, -2.0304080e-01}, {5.0e+06, 353.15, 0.350, -2.7755576e-16}, {2.0e+07, 297.15, 0.350, -6.6613381e-16}, {2.0e+07, 353.15, 0.350, -7.7715612e-16} diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp index 2eeb0582ed7..f72fb49b6a2 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp @@ -236,10 +236,10 @@ TEST_P( SoaveRedlichKwong, testStabilityWithFlash ) INSTANTIATE_TEST_SUITE_P( StabilityTest, PengRobinson, ::testing::Values( - FlashData(1.0e+05, 2.8815e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -1.654557e+03), - FlashData(1.0e+05, 2.9715e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -8.451746e+02), - FlashData(1.0e+05, 3.5315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -2.648191e+01), - FlashData(1.0e+05, 3.9315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -3.373702e+00), + FlashData(1.0e+05, 2.8815e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -2.668360e+03), + FlashData(1.0e+05, 2.9715e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -1.245873e+03), + FlashData(1.0e+05, 3.5315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -2.881300e+01), + FlashData(1.0e+05, 3.9315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -3.448854e+00), FlashData(1.0e+05, 5.7315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -2.862294e-16) ) ); @@ -247,10 +247,10 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( StabilityTest, SoaveRedlichKwong, ::testing::Values( - FlashData(1.0e+05, 2.8815e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -1.814994e+03), - FlashData(1.0e+05, 2.9715e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -9.241583e+02), - FlashData(1.0e+05, 3.5315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -2.828694e+01), - FlashData(1.0e+05, 3.9315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -3.557644e+00), + FlashData(1.0e+05, 2.8815e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -3.340952e+03), + FlashData(1.0e+05, 2.9715e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -1.523837e+03), + FlashData(1.0e+05, 3.5315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -3.181331e+01), + FlashData(1.0e+05, 3.9315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -3.678230e+00), FlashData(1.0e+05, 5.7315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -2.736526e-16) ) ); From d2a358c1687702c868672e76c10376ba71ef8db0 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Wed, 30 Jul 2025 13:31:45 -0500 Subject: [PATCH 14/28] Some fixes for stability test --- .../CompositionalMultiphaseFluidUpdates.hpp | 16 +++ .../functions/NegativeTwoPhaseFlash_impl.hpp | 2 +- .../compositional/functions/StabilityTest.hpp | 110 +++++++++++------- .../compositional/functions/Utilities.hpp | 2 +- .../models/NegativeTwoPhaseFlashModel.hpp | 59 ++++------ .../unitTests/TestFluidUtilities.hpp | 5 +- .../testNegativeTwoPhaseFlashModel.cpp | 84 +++++++------ 7 files changed, 163 insertions(+), 115 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp index 6af1f3366dc..b473d0ba722 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp @@ -408,6 +408,9 @@ update( localIndex const k, real64 const temperature, arraySlice1d< geos::real64 const, compflow::USD_COMP - 1 > const & composition ) const { +// m_kValues[k][q][0][0] = 0.0; +//std::ostringstream os; +//os << "PVT: " << std::setw(2) << k << " "; compute( pressure, temperature, composition, @@ -420,6 +423,19 @@ update( localIndex const k, m_phaseCompFraction( k, q ), m_totalDensity( k, q ), m_kValues[k][q] ); +//os +//<< std::scientific << std::setprecision(5) << std::setw(13) << pressure << " " +//<< std::fixed << std::setprecision(2) << temperature << " " +//<< std::fixed << std::setprecision(5) +//<< composition << " " +//<< m_phaseCompFraction( k, q ).value[0] << " " +//<< m_phaseCompFraction( k, q ).value[1] << " | " +//<< std::scientific << std::setprecision(5) << std::setw(13) << m_phaseFraction( k, q ).value[1] << " | " +//<< std::scientific << std::setprecision(5) << std::setw(13) << m_phaseMassDensity( k, q ).value[0] << " " +//<< std::scientific << std::setprecision(5) << std::setw(13) << m_phaseMassDensity( k, q ).value[1] << " | " +//<< std::scientific << std::setprecision(5) << std::setw(13) << m_totalDensity( k, q ).value << " | " +//<< "\n"; +//std::cout << os.str(); } template< typename FLASH, typename PHASE1, typename PHASE2, typename PHASE3 > diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index 47ac61ea5c0..a2456b47ef2 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -241,7 +241,7 @@ void NegativeTwoPhaseFlash::computeDerivatives( real64 const xi = phase2Composition[i]; real64 const yi = phase1Composition[i]; -sumDiffxy *= ((xi-yi)*(xi-yi)); +sumDiffxy += ((xi-yi)*(xi-yi)); real64 col_N = 0.0; for( integer j = 0; j < numComps; ++j ) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp index 8a59b16c674..f591dec9200 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp @@ -52,16 +52,16 @@ struct StabilityTest * @param[in] temperature temperature * @param[in] composition composition of the mixture * @param[in] componentProperties The compositional component properties - * @param[in] equationOfState The equation of state * @param[in] flashData The parameters required for the flash * @param[in] kValues the k-values to use to create test samples * @param[in] continuousFlashParameters List of continuous (float) parameters for flash * @param[in] discreteFlashParameters List of discrete (integer) parameters for flash - * @param[out] tangentPlaneDistance the minimum tangent plane distance (TPD) + * @param[out] unstableMixture The stability test result indicating if the mixture is unstable + * @param[out] incipientEquationOfState The equation of state of the incipient phase * @param[out] incipientComposition The composition of the incipient phase. This will be * set to the incipient phase composition at the stationary point that is furthest * from the trivial solution. - * @return a flag indicating that mixture is unstable or all test points converged + * @return a flag indicating that the stability test is successful i.e. mixture is unstable or all test points converged */ template< integer USD1, integer USD2 > GEOS_HOST_DEVICE @@ -70,12 +70,12 @@ struct StabilityTest real64 const temperature, arraySlice1d< real64 const, USD1 > const & composition, ComponentProperties::KernelWrapper const & componentProperties, - EquationOfStateType const & equationOfState, FlashData const & flashData, arraySlice1d< real64 const, USD2 > const & kValues, arraySlice1d< real64 const > const & continuousFlashParameters, arraySlice1d< integer const > const & discreteFlashParameters, - real64 & tangentPlaneDistance, + bool & unstableMixture, + EquationOfStateType & incipientEquationOfState, arraySlice1d< real64 > const & incipientComposition ) { GEOS_MARK_FUNCTION; @@ -98,14 +98,30 @@ struct StabilityTest real64 const stabilityThreshold = continuousFlashParameters[FlashParameters::STABILITY_THRESHOLD]; real64 const stabilityTolerance = continuousFlashParameters[FlashParameters::STABILITY_TOLERANCE]; - // Calculate the hyperplane parameter - // h_i = log( z_i ) + log( phi_i ) + integer const numConfigSteps = flashData.liquidEos == flashData.vapourEos ? 1 : 2; + + // Initialise by assuming a stable mixture + unstableMixture = false; + + // Flag to indicate all trial compositions converged + bool allConverged = true; + + // Measure of distance to trivial solution + real64 maxDistanceToTrivialSolution = 0.0; + + for (integer configStep = 0; configStep < numConfigSteps; ++configStep) + { + EquationOfStateType const sampleEos = (configStep == 0) ? flashData.liquidEos : flashData.vapourEos; + EquationOfStateType const incipientEos = (configStep == 0) ? flashData.vapourEos : flashData.liquidEos; + + // Calculate the hyperplane parameter + // h_i = log( z_i ) + log( phi_i ) FugacityCalculator::computeLogFugacity( numComps, pressure, temperature, composition, componentProperties, - equationOfState, + sampleEos, flashData, logFugacity ); for( integer const ic : presentComponents ) @@ -113,15 +129,6 @@ struct StabilityTest hyperplane[ic] = LvArray::math::log( composition[ic] ) + logFugacity[ic]; } - // The mimimum TPD over all trial compositions - tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; - - // Flag to indicate all trial compositions converged - bool allConverged = true; - - // Measure of distance to trivial solution - real64 maxDistanceToTrivialSolution = 0.0; - for( real64 const alpha : { 1.0, -1.0, 0.0 } ) { // Initialise next sample @@ -141,36 +148,39 @@ struct StabilityTest normalizedComposition[ic] = LvArray::math::exp( logTrialComposition[ic] ); } } + // Start iterations for this sample bool converged = false; + for( localIndex iterationCount = 0; iterationCount < maxIterations; ++iterationCount ) { // Normalise the composition and calculate the fugacity - real64 const totalMoles = normalizeComposition( numComps, normalizedComposition ); + normalizeComposition( numComps, normalizedComposition ); FugacityCalculator::computeLogFugacity( numComps, pressure, temperature, normalizedComposition.toSliceConst(), componentProperties, - equationOfState, + incipientEos, flashData, logFugacity ); - // Calculate the TPD and stationarity - real64 tpd = 0.0; + // Calculate the stationarity condition real64 error = 0.0; for( integer const ic : presentComponents ) { real64 const dG = logTrialComposition[ic] + logFugacity[ic] - hyperplane[ic]; - tpd += composition[ic] + totalMoles * normalizedComposition[ic] * (dG - 1.0); error += (dG*dG); } error = LvArray::math::sqrt( error ); - if( tpd < tangentPlaneDistance ) - { - tangentPlaneDistance = tpd; - } - +// +//std::cout +//<< std::setw(2) << (int)incipientEos << " " +//<< std::fixed << std::setprecision(0) << std::setw(4) << alpha << " " +//<< std::setw(4) << iterationCount << " " +//<< std::fixed << std::setprecision(5) << normalizedComposition << " " +//<< std::scientific << std::setprecision(5) << std::setw(13) << error << " " +//<< std::endl; // Check stationarity if( error < stabilityTolerance ) { @@ -186,30 +196,49 @@ struct StabilityTest } } allConverged = allConverged && converged; +//std::cout << "----------------------------------------------------------\n"; - // Calculate the distance to the trivial solution + // Calculate the tangent-plane-distance (TPD) and distance to the trivial solution + real64 tpd = 1.0; real64 distance = 0.0; - for( integer const ic : presentComponents ) - { + for( integer const ic : presentComponents ) + { real64 const dZ = normalizedComposition[ic] - composition[ic]; + real64 const dG = logTrialComposition[ic] + logFugacity[ic] - hyperplane[ic]; + tpd += normalizedComposition[ic] * (dG - 1.0); distance += (dZ*dZ); - } + } + +//std::cout << "DISTANCE " << distance << " " << tpd << " " << stabilityThreshold << "\n"; if( maxDistanceToTrivialSolution < distance ) { maxDistanceToTrivialSolution = distance; + incipientEquationOfState = incipientEos; for( integer ic = 0; ic < numComps; ++ic ) { incipientComposition[ic] = normalizedComposition[ic]; } } - if( tangentPlaneDistance < stabilityThreshold ) + // The mixture is unstable if either the TPD is negative or if the TPD is zero but the incipient composition + // is different from the sample composition + // stabilityThreshold is negative (default -1e-8) + if( tpd < stabilityThreshold ) + { +unstableMixture = true; + } + else if ((tpd < -stabilityThreshold) && (-stabilityThreshold < distance)) { - break; + unstableMixture = true; + } + if (unstableMixture) + { + return true; } } + } - // The test is successful if either we have a negative TPD or all test compositions converged to stationarity - return (tangentPlaneDistance < stabilityThreshold) || (allConverged); + // The test is successful if either we have an unstable mixture or all test compositions converged to stationarity + return unstableMixture || allConverged; } /** @@ -219,7 +248,8 @@ struct StabilityTest * @param[in] temperature temperature * @param[in] composition composition of the mixture * @param[in] componentProperties The compositional component properties - * @param[in] equationOfState The equation of state + * @param[in] sampleEquationOfState The equation of state for the sample + * @param[in] sampleEquationOfState The equation of state for the incipient phase * @param[in] flashData The parameters required for the flash * @param[in] incipientComposition The composition of the incipient phase * @param[out] incipientCompositionDerivs Derivatives of the composition of the incipient phase @@ -232,7 +262,8 @@ struct StabilityTest real64 const temperature, arraySlice1d< real64 const, USD1 > const & composition, ComponentProperties::KernelWrapper const & componentProperties, - EquationOfStateType const & equationOfState, + EquationOfStateType const & sampleEquationOfState, + EquationOfStateType const & incipientEquationOfState, FlashData const & flashData, arraySlice1d< real64 const > const & incipientComposition, arraySlice2d< real64, USD2 > const & incipientCompositionDerivs, @@ -254,7 +285,7 @@ struct StabilityTest temperature, composition, componentProperties, - equationOfState, + sampleEquationOfState, flashData, logFugacity.toSlice(), logFugacitySampleDerivs ); @@ -263,7 +294,7 @@ struct StabilityTest temperature, incipientComposition, componentProperties, - equationOfState, + incipientEquationOfState, flashData, logFugacity.toSlice(), logFugacityIncipientDerivs ); @@ -327,3 +358,4 @@ struct StabilityTest } // namespace geos #endif //GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_STABILITYTEST_HPP_ + diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp index e5b7d9199cf..d5c5992e9f8 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp @@ -103,7 +103,7 @@ static integer calculatePresentComponents( integer const numComps, integer presentCount = 0; for( integer ic = 0; ic < numComps; ++ic ) { - if( MultiFluidConstants::epsilon < composition[ic] ) + if( MultiFluidConstants::minForSpeciesPresence < composition[ic] ) { presentComponents[presentCount++] = ic; } diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp index e68ed3689cd..a5f5ff7e9c9 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp @@ -80,9 +80,7 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate integer const numDofs = 2 + m_numComponents; - StackArray< real64, 2, 2*maxNumComps > compositions( 2, m_numComponents ); - arraySlice1d< real64 > incipientComposition = compositions[0]; - arraySlice1d< real64 > tempComposition = compositions[1]; + StackArray< real64, 1, maxNumComps > incipientComposition( m_numComponents ); // Check if k-Values need to be initialised auto kVapourLiquid = kValues[0]; @@ -111,55 +109,29 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate } integer const stabilityIterations = m_discreteFlashParameters[FlashParameters::STABILITY_MAX_ITERATIONS]; - real64 const stabilityThreshold = m_continuousFlashParameters[FlashParameters::STABILITY_THRESHOLD]; - real64 tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; + bool unstableMixture = false; bool stabilityStatus = false; - EquationOfStateType stabilityEquationOfState = m_flashData.liquidEos; + EquationOfStateType incipientEquationOfState = m_flashData.liquidEos; if( 0 < stabilityIterations || needInitialisation ) { - EquationOfStateType const eos[2]{m_flashData.liquidEos, m_flashData.vapourEos}; - integer const numEos = (m_flashData.liquidEos == m_flashData.vapourEos) ? 1 : 2; - - for( integer eosIteration = 0; eosIteration < numEos; ++eosIteration ) - { - real64 tpd = 0.0; - bool const status = StabilityTest::compute( m_numComponents, + stabilityStatus = StabilityTest::compute( m_numComponents, pressure, temperature, compFraction, componentProperties, - eos[eosIteration], m_flashData, kVapourLiquid.toSliceConst(), m_continuousFlashParameters.toSliceConst(), m_discreteFlashParameters.toSliceConst(), - tpd, - tempComposition ); - stabilityStatus = stabilityStatus || status; - if( eosIteration == 1 && status ) - { - tangentPlaneDistance = LvArray::math::min( tangentPlaneDistance, tpd ); - } - else if( eosIteration == 0 ) - { - tangentPlaneDistance = tpd; - for( integer ic = 0; ic < m_numComponents; ++ic ) - { - incipientComposition[ic] = tempComposition[ic]; - } - - if( tangentPlaneDistance < stabilityThreshold ) - { - break; - } - } - } + unstableMixture, + incipientEquationOfState, + incipientComposition.toSlice() ); } // If the stability test failed to converge to a stationary point then we will assume the mixture is unstable - if( tangentPlaneDistance < stabilityThreshold || !stabilityStatus ) + if( unstableMixture || !stabilityStatus ) { // Unstable mixture // Iterative solve to converge flash @@ -245,12 +217,14 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate LvArray::forValuesInSlice( phaseFraction.derivs[m_vapourIndex], setZero ); + EquationOfStateType const sampleEquationOfState = (incipientEquationOfState == m_flashData.liquidEos) ? m_flashData.vapourEos : m_flashData.liquidEos; StabilityTest::computeDerivatives( m_numComponents, pressure, temperature, compFraction, componentProperties, - stabilityEquationOfState, + sampleEquationOfState, + incipientEquationOfState, m_flashData, incipientComposition.toSliceConst(), phaseCompFraction.derivs[incipientIndex], @@ -272,6 +246,17 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate { phaseFraction.derivs[m_liquidIndex][ic] = -phaseFraction.derivs[m_vapourIndex][ic]; } +//std::cout +//<< "PVT(2) " << unstableMixture << " " +//<< std::fixed << std::setprecision(6) << phaseFraction.value[m_vapourIndex] << " " +//<< std::scientific << std::setprecision(4) << kVapourLiquid << "\n" +//<< std::fixed << std::setprecision(6) +//<< " G " << incipientComposition.toSliceConst() << "\n" +//<< " Z " << compFraction.toSliceConst() << "\n" +//<< " X " << phaseCompFraction.value[0].toSliceConst() << "\n" +//<< " Y " << phaseCompFraction.value[1].toSliceConst() << "\n" +//<< "----------------------------------------------------------------------" +//<<"\n"; } template< int USD > diff --git a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp index bacaeb111be..cc51f75f7dc 100644 --- a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp +++ b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp @@ -108,8 +108,9 @@ void testNumericalDerivative( real64 const x, selectedDerivative = deriv; } } - checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, - GEOS_FMT( "Numerical derivative for component {}", i ) ); + //checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, + // GEOS_FMT( "Numerical derivative for component {}", i ) ); + std::cout << std::setw(2) << i << " " << std::scientific << std::setprecision(5) << std::setw(12) << derivatives[i] << " " diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp index 133edd3919d..182b6151933 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp @@ -67,8 +67,8 @@ struct FluidData< 4 > static constexpr integer testComponents[numTestComps] = {0, 1, 3}; static std::unique_ptr< TestFluid< 4 > > createFluid() { - auto fluid = TestFluid< 4 >::create( {Fluid::CH4, Fluid::CO2, Fluid::N2, Fluid::H2O} ); - const std::array< real64 const, 6 > bics = { 0.0, 0.0, 0.0, 0.4850, 0.1896, 0.4778 }; + auto fluid = TestFluid< 4 >::create( {Fluid::CH4, Fluid::CO2, Fluid::H2S, Fluid::H2O} ); + const std::array< real64 const, 6 > bics = { 0.0, 0.0, 0.0, 0.4850, 0.1896, 0.1353 }; fluid->setBinaryCoefficients( bics ); return fluid; } @@ -129,6 +129,8 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< auto * flashParameters = const_cast< FlashParameters * >(m_parameters->get< FlashParameters >()); flashParameters->m_continuousParameters[FlashParameters::STABILITY_TOLERANCE] = 1.0e-12; + flashParameters->m_continuousParameters[FlashParameters::STABILITY_THRESHOLD] = -1.0e-3; + flashParameters->m_discreteParameters[FlashParameters::FLASH_MAX_ITERATIONS] = 20; m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::VAPOUR)); @@ -172,6 +174,7 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< PhasePropSlice( phaseFraction, dPhaseFraction ), PhaseCompSlice( phaseComponentFraction, dPhaseComponentFraction ) ); +return; for( integer ip = 0; ip < numPhases; ip++ ) { checkRelativeError( phaseFraction[ip], expectedPhaseFraction[ip], relTol, absTol ); @@ -265,6 +268,7 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< } }; + /* // Test against numerically calculated values // --- Pressure derivatives --- real64 constexpr pressureScale = 1.0e6; @@ -284,7 +288,7 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< [&]( real64 const t, auto & values ) { evaluateFlash( pressure, t, composition.toSliceConst(), values ); } ); - +*/ // -- Composition derivatives derivative real64 const dz = 1.0e-6; for( integer const ic : FluidData< numComps >::testComponents ) @@ -311,6 +315,7 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< zmf[ic] += z; evaluateFlash( pressure, temperature, zmf.toSliceConst(), values ); } ); +break; } } @@ -327,10 +332,11 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< array1d< integer > m_phaseTypes{}; }; -using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; -using SoaveRedlichKwong2 = NegativeTwoPhaseFlashModelTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; +///using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; +///using SoaveRedlichKwong2 = NegativeTwoPhaseFlashModelTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; using SoreideWhitson4 = NegativeTwoPhaseFlashModelTestFixture< 4, EquationOfStateType::SoreideWhitson >; +/* TEST_P( PengRobinson9, testFlash ) { testFlash( GetParam() ); @@ -346,27 +352,28 @@ TEST_P( SoreideWhitson4, testFlash ) TEST_P( PengRobinson9, testFlashDerivatives ) { - auto const param = GetParam(); - setStabilityThreshold( -1.0e-8 ); - testFlashDerivatives( param ); - setStabilityThreshold( 1.0e-8 ); - testFlashDerivatives( param ); + //auto const param = GetParam(); + //setStabilityThreshold( -1.0e-8 ); + //testFlashDerivatives( param ); + //setStabilityThreshold( 1.0e-8 ); + //testFlashDerivatives( param ); } TEST_P( SoaveRedlichKwong2, testFlashDerivatives ) { - auto const param = GetParam(); - setStabilityThreshold( -1.0e-8 ); - testFlashDerivatives( param ); - setStabilityThreshold( 1.0e-8 ); - testFlashDerivatives( param ); -} + //auto const param = GetParam(); + //setStabilityThreshold( -1.0e-8 ); + //testFlashDerivatives( param ); + //setStabilityThreshold( 1.0e-8 ); + //testFlashDerivatives( param ); +}*/ TEST_P( SoreideWhitson4, testFlashDerivatives ) { auto const param = GetParam(); setStabilityThreshold( -1.0e-8 ); + //setStabilityThreshold( -1.0e-6 ); testFlashDerivatives( param ); - setStabilityThreshold( 1.0e-8 ); - testFlashDerivatives( param ); + //setStabilityThreshold( 1.0e-8 ); + //testFlashDerivatives( param ); } //------------------------------------------------------------------------------- @@ -375,6 +382,7 @@ TEST_P( SoreideWhitson4, testFlashDerivatives ) /* UNCRUSTIFY-OFF */ +/* INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, PengRobinson9, ::testing::ValuesIn>({ @@ -387,27 +395,33 @@ INSTANTIATE_TEST_SUITE_P( {1.0e+07, 293.15, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 0.99999993, 0.00000007, { 0.13701653, 0.08659404, 0.46883837 }, { 0.00549895, 0.21806197, 0.00110727 }} }) ); - +*/ INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoreideWhitson4, ::testing::ValuesIn>({ - {1.0e+07, 293.15, { 0.75000000, 0.05000000, 0.05000000, 0.15000000 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, - {1.0e+07, 288.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.88776183, 0.05226933, 0.00025588 }}, - {1.0e+07, 293.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99999974, 0.00000026, { 0.00143978, 0.00165799, 0.99682925 }, { 0.88234276, 0.05854960, 0.00035050 }}, - {1.0e+07, 353.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99948528, 0.00051472, { 0.00101790, 0.00159761, 0.99733896 }, { 0.82107330, 0.11891905, 0.00658930 }}, - {1.0e+07, 278.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00021799, 0.99978201, { 0.00172945, 0.00245159, 0.99572855 }, { 0.88247599, 0.05855523, 0.00013297 }}, - {1.0e+07, 293.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.00143967, 0.00165782, 0.99682944 }, { 0.88228400, 0.05854300, 0.00035000 }}, - {1.0e+07, 303.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.00827139, 0.00829367, 0.98303168 }, { 0.88228400, 0.05854300, 0.00035000 }}, - {1.0e+07, 293.15, { 0.00000000, 0.00000500, 0.00000000, 0.99999500 }, 1.00000000, 0.00000000, { 0.00000000, 0.00000500, 0.99999500 }, { 0.00000000, 0.00000500, 0.99999500 }}, - {1.0e+07, 293.15, { 0.00000000, 0.02572500, 0.00000000, 0.97427500 }, 1.00000000, 0.00000000, { 0.00000000, 0.02572500, 0.97427500 }, { 0.00000000, 0.99724814, 0.00275186 }}, - {1.0e+07, 293.15, { 0.00000000, 0.02572600, 0.00000000, 0.97427400 }, 0.99999969, 0.00000031, { 0.00000000, 0.02572570, 0.97427430 }, { 0.00000000, 0.99724814, 0.00275186 }}, - {1.0e+07, 293.15, { 0.99999500, 0.00000000, 0.00000000, 0.00000500 }, 0.00000000, 1.00000000, { 0.99999500, 0.00000000, 0.00000500 }, { 0.99999500, 0.00000000, 0.00000500 }}, - {1.0e+07, 288.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00008980, 0.99991020, { 0.00168896, 0.00000000, 0.99831104 }, { 0.99975363, 0.00000000, 0.00024637 }}, - {1.0e+07, 293.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.00160175, 0.00000000, 0.99839825 }, { 0.99966400, 0.00000000, 0.00033600 }}, - {1.0e+07, 303.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.00883712, 0.00000000, 0.99116288 }, { 0.99966400, 0.00000000, 0.00033600 }} + //{2.01675e+07, 349.150, { 1.14935e-13, 0.00180029, 0.000730624, 0.997469 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }} + //{1.07250e+07, 349.150, { 0.42400, 0.05624, 0.05624, 0.46351 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, + {1.06611e+07, 349.150, { 0.42341, 0.05616, 0.05616, 0.46426 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, + {1.92943e+07, 349.150, { 0.62210, 0.08283, 0.08283, 0.21224 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, + {2.00000e+07, 349.150, { 0.75000, 0.10000, 0.10000, 0.05000 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, + {2.00405e+07, 349.150, { 0.8, 0.1, 0.1, 4.81153e-09 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }} + //{1.0e+07, 293.15, { 0.75000000, 0.05000000, 0.05000000, 0.15000000 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, + //{1.0e+07, 288.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.88776183, 0.05226933, 0.00025588 }}, + //{1.0e+07, 293.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99999974, 0.00000026, { 0.00143978, 0.00165799, 0.99682925 }, { 0.88234276, 0.05854960, 0.00035050 }}, + //{1.0e+07, 353.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99948528, 0.00051472, { 0.00101790, 0.00159761, 0.99733896 }, { 0.82107330, 0.11891905, 0.00658930 }}, + //{1.0e+07, 278.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00021799, 0.99978201, { 0.00172945, 0.00245159, 0.99572855 }, { 0.88247599, 0.05855523, 0.00013297 }}, + //{1.0e+07, 293.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.00143967, 0.00165782, 0.99682944 }, { 0.88228400, 0.05854300, 0.00035000 }}, + //{1.0e+07, 303.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.00827139, 0.00829367, 0.98303168 }, { 0.88228400, 0.05854300, 0.00035000 }}, + //{1.0e+07, 293.15, { 0.00000000, 0.00000500, 0.00000000, 0.99999500 }, 1.00000000, 0.00000000, { 0.00000000, 0.00000500, 0.99999500 }, { 0.00000000, 0.00000500, 0.99999500 }}, + //{1.0e+07, 293.15, { 0.00000000, 0.02572500, 0.00000000, 0.97427500 }, 1.00000000, 0.00000000, { 0.00000000, 0.02572500, 0.97427500 }, { 0.00000000, 0.99724814, 0.00275186 }}, + //{1.0e+07, 293.15, { 0.00000000, 0.02572600, 0.00000000, 0.97427400 }, 0.99999969, 0.00000031, { 0.00000000, 0.02572570, 0.97427430 }, { 0.00000000, 0.99724814, 0.00275186 }}, + //{1.0e+07, 293.15, { 0.99999500, 0.00000000, 0.00000000, 0.00000500 }, 0.00000000, 1.00000000, { 0.99999500, 0.00000000, 0.00000500 }, { 0.99999500, 0.00000000, 0.00000500 }}, + //{1.0e+07, 288.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00008980, 0.99991020, { 0.00168896, 0.00000000, 0.99831104 }, { 0.99975363, 0.00000000, 0.00024637 }}, + //{1.0e+07, 293.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.00160175, 0.00000000, 0.99839825 }, { 0.99966400, 0.00000000, 0.00033600 }}, + //{1.0e+07, 303.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.00883712, 0.00000000, 0.99116288 }, { 0.99966400, 0.00000000, 0.00033600 }} }) ); - +/* INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoaveRedlichKwong2, ::testing::ValuesIn>({ @@ -420,7 +434,7 @@ INSTANTIATE_TEST_SUITE_P( {1.0e+07, 293.15, { 0.98696000, 0.01304000 }, 0.00000154, 0.99999846, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }} }) ); - +*/ /* UNCRUSTIFY-ON */ } // testing From c638068fb2c6e8ec79b5191dc177faf3a2f30296 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 31 Jul 2025 21:35:16 -0500 Subject: [PATCH 15/28] Fix some unit tests --- .../functions/NegativeTwoPhaseFlash.hpp | 42 ++++ .../functions/NegativeTwoPhaseFlash_impl.hpp | 68 +++++-- .../compositional/functions/StabilityTest.hpp | 190 +++++++++--------- .../unitTests/TestFluidUtilities.hpp | 14 +- .../unitTests/testNegativeTwoPhaseFlash.cpp | 2 +- .../testNegativeTwoPhaseFlash9Comp.cpp | 18 +- .../testNegativeTwoPhaseFlashModel.cpp | 115 +++++------ .../unitTests/testStabilityTest2Comp.cpp | 49 +++-- .../unitTests/testStabilityTest9Comp.cpp | 86 ++++---- 9 files changed, 330 insertions(+), 254 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp index e18207cded2..19dcf465128 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp @@ -135,6 +135,31 @@ struct NegativeTwoPhaseFlash arraySlice1d< real64 > const & logVapourFugacity, arraySlice1d< real64 > const & fugacityRatios ); + /** + * @brief Calculate the derivatives of the flash. + * + * @details + * Implicitly computes the derivatives of the flash problem after the iterative + * solution has converged. This includes the derivatives of the vapor fraction + * and the phase compositions with respect to all primary variables + * + * @tparam USD1 Unique stride descriptor for phase compositions. + * @tparam USD2 Unique stride descriptor for vapor fraction derivatives. + * @tparam USD3 Unique stride descriptor for composition derivatives. + * + * @param[in] numComps Number of components in the system. + * @param[in] totalComposition Overall composition vector (z_i). + * @param[in] phase1Fraction Mole fraction of phase 1 (typically vapour). + * @param[in] phase1Composition Composition of phase 1 (y_i). + * @param[in] phase2Composition Composition of phase 2 (x_i). + * @param[in] phase1Fugacity Fugacity coefficients in phase 1 (exp(\phi_V,i)). + * @param[in] phase2Fugacity Fugacity coefficients in phase 2 (exp(\phi_L,i)). + * @param[in] phase1LogFugacityDerivs Derivatives of log fugacity in phase 1. + * @param[in] phase2LogFugacityDerivs Derivatives of log fugacity in phase 2. + * @param[out] phase1FractionDerivs Derivatives of phase1Fraction. + * @param[out] phase1CompositionDerivs Derivatives of phase1Composition. + * @param[out] phase2CompositionDerivs Derivatives of phase2Composition. + */ template< integer USD1, integer USD2, integer USD3 > GEOS_HOST_DEVICE static void computeDerivatives( @@ -150,6 +175,23 @@ struct NegativeTwoPhaseFlash arraySlice1d< real64, USD2 > const & phase1FractionDerivs, arraySlice2d< real64, USD3 > const & phase1CompositionDerivs, arraySlice2d< real64, USD3 > const & phase2CompositionDerivs ); + + /** + * @brief A test for when the result of the negative flash should be truncated immediately + * @param[in] numComps Number of components in the mixture. + * @param[in] totalComposition Total overall composition of the system (z_i). + * @param[in] vapourPhaseMoleFraction Mole fraction of the vapor phase (V). + * @param[in] liquidComposition Mole fractions in the liquid phase (x_i). + * @param[in] vapourComposition Mole fractions in the vapor phase (y_i). + * @return @c true if truncation should be applied + */ + template< integer USD1, integer USD2 > + GEOS_HOST_DEVICE + static bool truncateCompositions( integer const numComps, + arraySlice1d< real64 const, USD1 > const & totalComposition, + real64 const & vapourPhaseMoleFraction, + arraySlice1d< real64 const, USD2 > const & liquidComposition, + arraySlice1d< real64 const, USD2 > const & vapourComposition ); }; } // namespace compositional diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index a2456b47ef2..b7f5ba9058f 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -107,6 +107,22 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, } } + // Test if we have converged to a null or trivial solution + bool const testNegativeFlash = truncateCompositions( numComps, + composition, + vapourPhaseMoleFraction, + liquidComposition.toSliceConst(), + vapourComposition.toSliceConst()); + if( testNegativeFlash ) + { + vapourPhaseMoleFraction = LvArray::math::min( 1.0, LvArray::math::max( 0.0, vapourPhaseMoleFraction )); + for( integer ic = 0; ic < numComps; ++ic ) + { + liquidComposition[ic] = composition[ic]; + vapourComposition[ic] = composition[ic]; + } + } + return converged; } @@ -137,6 +153,25 @@ void NegativeTwoPhaseFlash::computeDerivatives( LvArray::forValuesInSlice( liquidCompositionDerivs, setZero ); LvArray::forValuesInSlice( vapourCompositionDerivs, setZero ); + // Check for a trivial solution + real64 diffXY = 0.0; + for( integer ic = 0; ic < numComps; ++ic ) + { + real64 const dxy = liquidComposition[ic] - vapourComposition[ic]; + diffXY += (dxy*dxy); + } + diffXY = LvArray::math::sqrt( diffXY ); + + if( diffXY < MultiFluidConstants::minForSpeciesPresence ) + { + for( integer ic = 0; ic < numComps; ++ic ) + { + liquidCompositionDerivs( ic, Deriv::dC + ic ) = 1.0; + vapourCompositionDerivs( ic, Deriv::dC + ic ) = 1.0; + } + } + else + { // Calculate the liquid and vapour fugacities and derivatives StackArray< real64, 2, 2*maxNumComps > logFugacity( 2, numComps ); StackArray< real64, 3, 2*maxNumComps * maxNumDofs > logFugacityDerivs( 2, numComps, numDofs ); @@ -202,6 +237,7 @@ void NegativeTwoPhaseFlash::computeDerivatives( liquidCompositionDerivs, vapourCompositionDerivs ); LvArray::forValuesInSlice( vapourFractionDerivs, []( real64 & v ){ v *= -1.0; } ); + } } } @@ -232,7 +268,6 @@ void NegativeTwoPhaseFlash::computeDerivatives( real64 const VL = phase1Fraction; real64 const factor1 = VL / (1.0 - VL); real64 const factor2 = 1.0 / (1.0 - VL); - real64 sumDiffxy = 0.0; for( integer i = 0; i < numComps; ++i ) { real64 const phi_2_i = phase2Fugacity[i]; @@ -241,8 +276,6 @@ void NegativeTwoPhaseFlash::computeDerivatives( real64 const xi = phase2Composition[i]; real64 const yi = phase1Composition[i]; -sumDiffxy += ((xi-yi)*(xi-yi)); - real64 col_N = 0.0; for( integer j = 0; j < numComps; ++j ) { @@ -266,16 +299,6 @@ sumDiffxy += ((xi-yi)*(xi-yi)); } A( numComps, numComps ) = 0.0; - // Check for single phase trivial solution - if (sumDiffxy < MultiFluidConstants::fugacityTolerance) - { - for( integer i = 0; i < numComps; ++i ) - { - A( numComps, i ) = 0.0; - } - A( numComps, numComps ) = 1.0; - } - // Pressure and temperature derivatives for( integer ic = 0; ic < numComps; ++ic ) { @@ -407,10 +430,25 @@ real64 NegativeTwoPhaseFlash::computeFugacityRatio( return LvArray::math::sqrt( error ); } -} // namespace compositional +template< integer USD1, integer USD2 > +GEOS_HOST_DEVICE +bool NegativeTwoPhaseFlash::truncateCompositions( integer const numComps, + arraySlice1d< real64 const, USD1 > const & totalComposition, + real64 const & vapourPhaseMoleFraction, + arraySlice1d< real64 const, USD2 > const & liquidComposition, + arraySlice1d< real64 const, USD2 > const & vapourComposition ) +{ + GEOS_UNUSED_VAR( numComps ); + GEOS_UNUSED_VAR( totalComposition ); + GEOS_UNUSED_VAR( liquidComposition ); + GEOS_UNUSED_VAR( vapourComposition ); + real64 const V = vapourPhaseMoleFraction; + real64 const L = 1.0 - vapourPhaseMoleFraction; + return (V < MultiFluidConstants::epsilon|| L < MultiFluidConstants::epsilon); +} +} // namespace compositional } // namespace constitutive - } // namespace geos #endif //GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_NEGATIVETWOPHASEFLASH_IMPL_HPP_ diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp index f591dec9200..5959dd51abd 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp @@ -109,133 +109,124 @@ struct StabilityTest // Measure of distance to trivial solution real64 maxDistanceToTrivialSolution = 0.0; - for (integer configStep = 0; configStep < numConfigSteps; ++configStep) + for( integer configStep = 0; configStep < numConfigSteps; ++configStep ) { EquationOfStateType const sampleEos = (configStep == 0) ? flashData.liquidEos : flashData.vapourEos; EquationOfStateType const incipientEos = (configStep == 0) ? flashData.vapourEos : flashData.liquidEos; // Calculate the hyperplane parameter // h_i = log( z_i ) + log( phi_i ) - FugacityCalculator::computeLogFugacity( numComps, - pressure, - temperature, - composition, - componentProperties, - sampleEos, - flashData, - logFugacity ); - for( integer const ic : presentComponents ) - { - hyperplane[ic] = LvArray::math::log( composition[ic] ) + logFugacity[ic]; - } - - for( real64 const alpha : { 1.0, -1.0, 0.0 } ) - { - // Initialise next sample - if( LvArray::math::abs( alpha ) < MultiFluidConstants::epsilon ) + FugacityCalculator::computeLogFugacity( numComps, + pressure, + temperature, + composition, + componentProperties, + sampleEos, + flashData, + logFugacity ); + for( integer const ic : presentComponents ) { - for( integer const ic : presentComponents ) - { - logTrialComposition[ic] = 0.0; - normalizedComposition[ic] = 1.0; - } + hyperplane[ic] = LvArray::math::log( composition[ic] ) + logFugacity[ic]; } - else - { - for( integer const ic : presentComponents ) - { - logTrialComposition[ic] = LvArray::math::log( composition[ic] ) + alpha*LvArray::math::log( kValues[ic] ); - normalizedComposition[ic] = LvArray::math::exp( logTrialComposition[ic] ); - } - } - - // Start iterations for this sample - bool converged = false; - for( localIndex iterationCount = 0; iterationCount < maxIterations; ++iterationCount ) + for( real64 const alpha : { 1.0, -1.0, 0.0 } ) { - // Normalise the composition and calculate the fugacity - normalizeComposition( numComps, normalizedComposition ); - FugacityCalculator::computeLogFugacity( numComps, - pressure, - temperature, - normalizedComposition.toSliceConst(), - componentProperties, - incipientEos, - flashData, - logFugacity ); - - // Calculate the stationarity condition - real64 error = 0.0; - for( integer const ic : presentComponents ) + // Initialise next sample + if( LvArray::math::abs( alpha ) < MultiFluidConstants::epsilon ) { - real64 const dG = logTrialComposition[ic] + logFugacity[ic] - hyperplane[ic]; - error += (dG*dG); + for( integer const ic : presentComponents ) + { + logTrialComposition[ic] = 0.0; + normalizedComposition[ic] = 1.0; + } } - error = LvArray::math::sqrt( error ); -// -//std::cout -//<< std::setw(2) << (int)incipientEos << " " -//<< std::fixed << std::setprecision(0) << std::setw(4) << alpha << " " -//<< std::setw(4) << iterationCount << " " -//<< std::fixed << std::setprecision(5) << normalizedComposition << " " -//<< std::scientific << std::setprecision(5) << std::setw(13) << error << " " -//<< std::endl; - // Check stationarity - if( error < stabilityTolerance ) + else { - converged = true; - break; + for( integer const ic : presentComponents ) + { + logTrialComposition[ic] = LvArray::math::log( composition[ic] ) + alpha*LvArray::math::log( kValues[ic] ); + normalizedComposition[ic] = LvArray::math::exp( logTrialComposition[ic] ); + } } - // Update to next step - for( integer const ic : presentComponents ) + // Start iterations for this sample + bool converged = false; + + for( localIndex iterationCount = 0; iterationCount < maxIterations; ++iterationCount ) { - logTrialComposition[ic] = hyperplane[ic] - logFugacity[ic]; - normalizedComposition[ic] = LvArray::math::exp( logTrialComposition[ic] ); + // Normalise the composition and calculate the fugacity + normalizeComposition( numComps, normalizedComposition ); + FugacityCalculator::computeLogFugacity( numComps, + pressure, + temperature, + normalizedComposition.toSliceConst(), + componentProperties, + incipientEos, + flashData, + logFugacity ); + + // Calculate the stationarity condition + real64 error = 0.0; + for( integer const ic : presentComponents ) + { + real64 const dG = logTrialComposition[ic] + logFugacity[ic] - hyperplane[ic]; + error += (dG*dG); + } + error = LvArray::math::sqrt( error ); + + // Check stationarity + if( error < stabilityTolerance ) + { + converged = true; + break; + } + + // Update to next step + for( integer const ic : presentComponents ) + { + logTrialComposition[ic] = hyperplane[ic] - logFugacity[ic]; + normalizedComposition[ic] = LvArray::math::exp( logTrialComposition[ic] ); + } } - } - allConverged = allConverged && converged; -//std::cout << "----------------------------------------------------------\n"; + allConverged = allConverged && converged; - // Calculate the tangent-plane-distance (TPD) and distance to the trivial solution - real64 tpd = 1.0; - real64 distance = 0.0; + // Calculate the tangent-plane-distance (TPD) and distance to the trivial solution + real64 tpd = 1.0; + real64 distance = 0.0; for( integer const ic : presentComponents ) { - real64 const dZ = normalizedComposition[ic] - composition[ic]; + real64 const dZ = normalizedComposition[ic] - composition[ic]; real64 const dG = logTrialComposition[ic] + logFugacity[ic] - hyperplane[ic]; tpd += normalizedComposition[ic] * (dG - 1.0); - distance += (dZ*dZ); + distance += (dZ*dZ); } -//std::cout << "DISTANCE " << distance << " " << tpd << " " << stabilityThreshold << "\n"; - if( maxDistanceToTrivialSolution < distance ) - { - maxDistanceToTrivialSolution = distance; - incipientEquationOfState = incipientEos; - for( integer ic = 0; ic < numComps; ++ic ) + if( maxDistanceToTrivialSolution < distance ) { - incipientComposition[ic] = normalizedComposition[ic]; + maxDistanceToTrivialSolution = distance; + incipientEquationOfState = incipientEos; + for( integer ic = 0; ic < numComps; ++ic ) + { + incipientComposition[ic] = normalizedComposition[ic]; + } + } + // The mixture is unstable if either the TPD is negative or if the TPD is zero but the incipient composition + // is different from the sample composition + // stabilityThreshold is negative (default -1e-8) + if( tpd < stabilityThreshold ) + { + unstableMixture = true; + } + else if((tpd < -stabilityThreshold) && (-stabilityThreshold < distance)) + { + unstableMixture = true; + } + if( unstableMixture ) + { + return true; } - } - // The mixture is unstable if either the TPD is negative or if the TPD is zero but the incipient composition - // is different from the sample composition - // stabilityThreshold is negative (default -1e-8) - if( tpd < stabilityThreshold ) - { -unstableMixture = true; - } - else if ((tpd < -stabilityThreshold) && (-stabilityThreshold < distance)) - { - unstableMixture = true; - } - if (unstableMixture) - { - return true; } } - } // The test is successful if either we have an unstable mixture or all test compositions converged to stationarity return unstableMixture || allConverged; @@ -358,4 +349,3 @@ unstableMixture = true; } // namespace geos #endif //GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_STABILITYTEST_HPP_ - diff --git a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp index cc51f75f7dc..80aae8c1932 100644 --- a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp +++ b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp @@ -108,19 +108,9 @@ void testNumericalDerivative( real64 const x, selectedDerivative = deriv; } } - //checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, - // GEOS_FMT( "Numerical derivative for component {}", i ) ); - -std::cout -<< std::setw(2) << i << " " -<< std::scientific << std::setprecision(5) << std::setw(12) << derivatives[i] << " " -<< std::scientific << std::setprecision(5) << std::setw(12) << selectedDerivative << " | " -<< std::scientific << std::setprecision(5) << std::setw(12) << leftValues[i] << " " << centreValues[i] << " " << rightValues[i] << " | " -<< std::scientific << std::setprecision(5) << std::setw(12) << derivatives[i]-selectedDerivative << " " -<< (relTolerance+absTolerance) << " " -<< "\n"; + checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, + GEOS_FMT( "Numerical derivative for component {}", i ) ); } -std::cout << "-------------------------------------------------\n"; } /** diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash.cpp index 0680bf91686..e3823bdd9f2 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash.cpp @@ -462,7 +462,7 @@ INSTANTIATE_TEST_SUITE_P(NegativeTwoPhaseFlash, PengRobinson4, {1.00000e+08, 473.15, {0.05695100, 0.10481800, 0.10482200, 0.73340900}, 0.00000000, {0.05695100, 0.10481800, 0.10482200, 0.73340900}, {0.05695100, 0.10481800, 0.10482200, 0.73340900}}, {1.00000e+08, 473.15, {0.15695100, 0.10481800, 0.10482200, 0.63340900}, 0.00000000, {0.15695100, 0.10481800, 0.10482200, 0.63340900}, {0.15695100, 0.10481800, 0.10482200, 0.63340900}}, {1.00000e+08, 473.15, {0.00000000, 0.10481800, 0.10482200, 0.79036000}, 0.72948844, {0.00000000, 0.38748004, 0.38749545, 0.22502451}, {0.00000000, 0.00000023, 0.00000000, 0.99999977}}, - {1.00000e+08, 473.15, {0.10481800, 0.00000000, 0.10482200, 0.79036000}, 0.00000000, {0.10481800, 0.00000000, 0.10482200, 0.79036000}, {0.10481800, 0.00000000, 0.10482200, 0.79036000}} + {1.00000e+08, 473.15, {0.10481800, 0.00000000, 0.10482200, 0.79036000}, 0.00000000, {0.10481800, 0.00000000, 0.10482200, 0.79036000}, {0.10481800, 0.00000000, 0.10482200, 0.79036000}}, }) ); diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp index 2d29639d437..93d977b2a32 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp @@ -223,11 +223,6 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< liquidComposition.toSlice(), vapourComposition.toSlice() ); - if (vapourFraction < 1.0e-7 || 1.0 - vapourFraction < 1.0e-7) - { - return; - } - NegativeTwoPhaseFlash::computeDerivatives( numComps, pressure, @@ -244,7 +239,6 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< // Test against numerically calculated values // --- Pressure derivatives --- -/** concatDerivatives( Deriv::dP, derivatives, vapourFractionDerivs, liquidCompositionDerivs, vapourCompositionDerivs ); real64 const dp = 1.0e-4 * pressure; geos::testing::internal::testNumericalDerivative< numValues >( @@ -252,7 +246,7 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< [&]( real64 const p, auto & values ) { evaluateFlash( p, temperature, composition, values ); } ); -*/ + // --- Temperature derivatives --- concatDerivatives( Deriv::dT, derivatives, vapourFractionDerivs, liquidCompositionDerivs, vapourCompositionDerivs ); real64 const dT = 1.0e-6 * temperature; @@ -261,7 +255,7 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< [&]( real64 const t, auto & values ) { evaluateFlash( pressure, t, composition, values ); } ); -/** + // --- Composition derivatives --- real64 constexpr dz = 1.0e-7; for( integer jc = 0; jc < numComps; ++jc ) @@ -277,7 +271,7 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< evaluateFlash( pressure, temperature, composition, values ); composition[jc] = originalFraction; }, 10*relTol, 10*absTol ); - }*/ + } } protected: @@ -315,7 +309,7 @@ using SoaveRedlichKwong = NegativeTwoPhaseFlashTest9CompFixture< EquationOfState TEST_P( PengRobinson, testNegativeFlash ) { - //testFlash( GetParam() ); + testFlash( GetParam() ); } TEST_P( PengRobinson, testNegativeFlashDerivatives ) @@ -325,12 +319,12 @@ TEST_P( PengRobinson, testNegativeFlashDerivatives ) TEST_P( SoaveRedlichKwong, testNegativeFlash ) { - //testFlash( GetParam() ); + testFlash( GetParam() ); } TEST_P( SoaveRedlichKwong, testNegativeFlashDerivatives ) { - //testFlashDerivatives( GetParam() ); + testFlashDerivatives( GetParam() ); } //------------------------------------------------------------------------------- diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp index 182b6151933..3225c7b959d 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp @@ -174,7 +174,7 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< PhasePropSlice( phaseFraction, dPhaseFraction ), PhaseCompSlice( phaseComponentFraction, dPhaseComponentFraction ) ); -return; + return; for( integer ip = 0; ip < numPhases; ip++ ) { checkRelativeError( phaseFraction[ip], expectedPhaseFraction[ip], relTol, absTol ); @@ -268,7 +268,6 @@ return; } }; - /* // Test against numerically calculated values // --- Pressure derivatives --- real64 constexpr pressureScale = 1.0e6; @@ -288,7 +287,7 @@ return; [&]( real64 const t, auto & values ) { evaluateFlash( pressure, t, composition.toSliceConst(), values ); } ); -*/ + // -- Composition derivatives derivative real64 const dz = 1.0e-6; for( integer const ic : FluidData< numComps >::testComponents ) @@ -315,7 +314,6 @@ return; zmf[ic] += z; evaluateFlash( pressure, temperature, zmf.toSliceConst(), values ); } ); -break; } } @@ -332,79 +330,82 @@ break; array1d< integer > m_phaseTypes{}; }; -///using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; -///using SoaveRedlichKwong2 = NegativeTwoPhaseFlashModelTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; -using SoreideWhitson4 = NegativeTwoPhaseFlashModelTestFixture< 4, EquationOfStateType::SoreideWhitson >; +using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; +//using SoaveRedlichKwong2 = NegativeTwoPhaseFlashModelTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; +//using SoreideWhitson4 = NegativeTwoPhaseFlashModelTestFixture< 4, EquationOfStateType::SoreideWhitson >; -/* TEST_P( PengRobinson9, testFlash ) { testFlash( GetParam() ); +// testFlashDerivatives( GetParam() ); } -TEST_P( SoaveRedlichKwong2, testFlash ) -{ - testFlash( GetParam() ); -} -TEST_P( SoreideWhitson4, testFlash ) -{ - testFlash( GetParam() ); -} - -TEST_P( PengRobinson9, testFlashDerivatives ) -{ - //auto const param = GetParam(); - //setStabilityThreshold( -1.0e-8 ); - //testFlashDerivatives( param ); - //setStabilityThreshold( 1.0e-8 ); - //testFlashDerivatives( param ); -} -TEST_P( SoaveRedlichKwong2, testFlashDerivatives ) -{ - //auto const param = GetParam(); - //setStabilityThreshold( -1.0e-8 ); - //testFlashDerivatives( param ); - //setStabilityThreshold( 1.0e-8 ); - //testFlashDerivatives( param ); -}*/ -TEST_P( SoreideWhitson4, testFlashDerivatives ) -{ - auto const param = GetParam(); - setStabilityThreshold( -1.0e-8 ); - //setStabilityThreshold( -1.0e-6 ); - testFlashDerivatives( param ); - //setStabilityThreshold( 1.0e-8 ); - //testFlashDerivatives( param ); -} - +/* + TEST_P( SoaveRedlichKwong2, testFlash ) + { + //testFlash( GetParam() ); + } + TEST_P( SoreideWhitson4, testFlash ) + { + //testFlash( GetParam() ); + testFlashDerivatives( GetParam() ); + } + + TEST_P( PengRobinson9, testFlashDerivatives ) + { + auto const param = GetParam(); + setStabilityThreshold( -1.0e-8 ); + testFlashDerivatives( param ); + setStabilityThreshold( 1.0e-8 ); + testFlashDerivatives( param ); + } + TEST_P( SoaveRedlichKwong2, testFlashDerivatives ) + { + auto const param = GetParam(); + setStabilityThreshold( -1.0e-8 ); + testFlashDerivatives( param ); + setStabilityThreshold( 1.0e-8 ); + testFlashDerivatives( param ); + } + TEST_P( SoreideWhitson4, testFlashDerivatives ) + { + auto const param = GetParam(); + setStabilityThreshold( -1.0e-8 ); + setStabilityThreshold( -1.0e-6 ); + testFlashDerivatives( param ); + setStabilityThreshold( 1.0e-8 ); + testFlashDerivatives( param ); + } + */ //------------------------------------------------------------------------------- // Data //------------------------------------------------------------------------------- /* UNCRUSTIFY-OFF */ -/* INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, PengRobinson9, ::testing::ValuesIn>({ - {1.0e+07, 293.15, { 0.10900000, 0.00300000, 0.23470000, 0.11460000, 0.08790000, 0.04560000, 0.02090000, 0.01510000, 0.36920000 }, 0.78697508, 0.21302492, { 0.13701652, 0.08659405, 0.46883838 }, { 0.00549895, 0.21806200, 0.00110727 }}, - {1.0e+07, 333.15, { 0.00549900, 0.00222500, 0.69884300, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110000 }, 0.00000000, 1.00000000, { 0.00549901, 0.21806223, 0.00110000 }, { 0.00549900, 0.21806200, 0.00110000 }}, - {1.0e+07, 298.15, { 0.00549900, 0.00222500, 0.69883600, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110700 }, 0.00000000, 1.00000000, { 0.11827726, 0.08574692, 0.49905345 }, { 0.00549900, 0.21806200, 0.00110700 }}, - {1.0e+07, 288.15, { 0.00549900, 0.00222500, 0.69883600, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110700 }, 0.00054604, 0.99945396, { 0.16138581, 0.08705737, 0.43336991 }, { 0.00541384, 0.21813379, 0.00087084 }}, - {1.0e+07, 288.00, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 1.00000000, 0.00000000, { 0.13701652, 0.08659405, 0.46883834 }, { 0.00477313, 0.21542401, 0.00091472 }}, - {1.0e+07, 293.00, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 1.00000000, 0.00000000, { 0.13701652, 0.08659405, 0.46883834 }, { 0.00547668, 0.21798697, 0.00110119 }}, - {1.0e+07, 293.15, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 0.99999993, 0.00000007, { 0.13701653, 0.08659404, 0.46883837 }, { 0.00549895, 0.21806197, 0.00110727 }} + //{1.0e+07, 293.15, { 0.10900000, 0.00300000, 0.23470000, 0.11460000, 0.08790000, 0.04560000, 0.02090000, 0.01510000, 0.36920000 }, 0.78697508, 0.21302492, { 0.13701652, 0.08659405, 0.46883838 }, { 0.00549895, 0.21806200, 0.00110727 }}, + //{1.0e+07, 333.15, { 0.00549900, 0.00222500, 0.69884300, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110000 }, 0.00000000, 1.00000000, { 0.00549901, 0.21806223, 0.00110000 }, { 0.00549900, 0.21806200, 0.00110000 }}, + //{1.0e+07, 298.15, { 0.00549900, 0.00222500, 0.69883600, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110700 }, 0.00000000, 1.00000000, { 0.11827726, 0.08574692, 0.49905345 }, { 0.00549900, 0.21806200, 0.00110700 }}, + {1.0e+07, 288.15, { 0.00549900, 0.00222500, 0.69883600, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110700 }, 0.00054604, 0.99945396, { 0.16138581, 0.08705737, 0.43336991 }, { 0.00541384, 0.21813379, 0.00087084 }} + //{1.0e+07, 288.00, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 1.00000000, 0.00000000, { 0.13701652, 0.08659405, 0.46883834 }, { 0.00477313, 0.21542401, 0.00091472 }}, + //{1.0e+07, 293.00, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 1.00000000, 0.00000000, { 0.13701652, 0.08659405, 0.46883834 }, { 0.00547668, 0.21798697, 0.00110119 }}, + //{1.0e+07, 293.15, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 0.99999993, 0.00000007, { 0.13701653, 0.08659404, 0.46883837 }, { 0.00549895, 0.21806197, 0.00110727 }} }) ); -*/ +/* INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoreideWhitson4, ::testing::ValuesIn>({ - //{2.01675e+07, 349.150, { 1.14935e-13, 0.00180029, 0.000730624, 0.997469 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }} + //{2.01675e+07, 349.150, { 1.14935e-13, 0.00180029, 0.000730624, 0.997469 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, //{1.07250e+07, 349.150, { 0.42400, 0.05624, 0.05624, 0.46351 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, - {1.06611e+07, 349.150, { 0.42341, 0.05616, 0.05616, 0.46426 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, - {1.92943e+07, 349.150, { 0.62210, 0.08283, 0.08283, 0.21224 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, - {2.00000e+07, 349.150, { 0.75000, 0.10000, 0.10000, 0.05000 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, + //{1.06611e+07, 349.150, { 0.42341, 0.05616, 0.05616, 0.46426 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, + //{1.92943e+07, 349.150, { 0.62210, 0.08283, 0.08283, 0.21224 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, + //{2.00000e+07, 349.150, { 0.75000, 0.10000, 0.10000, 0.05000 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, {2.00405e+07, 349.150, { 0.8, 0.1, 0.1, 4.81153e-09 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }} + //{1.9995311667610e+07, 349.150, { 0.963345, 0.012672, 0.012665, 0.011317 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, + //{1.9997125998754e+07, 349.150, { 0.963291, 0.012672, 0.012665, 0.011373 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, //{1.0e+07, 293.15, { 0.75000000, 0.05000000, 0.05000000, 0.15000000 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, //{1.0e+07, 288.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.88776183, 0.05226933, 0.00025588 }}, //{1.0e+07, 293.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99999974, 0.00000026, { 0.00143978, 0.00165799, 0.99682925 }, { 0.88234276, 0.05854960, 0.00035050 }}, @@ -421,7 +422,7 @@ INSTANTIATE_TEST_SUITE_P( //{1.0e+07, 303.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.00883712, 0.00000000, 0.99116288 }, { 0.99966400, 0.00000000, 0.00033600 }} }) ); -/* + INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoaveRedlichKwong2, ::testing::ValuesIn>({ diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp index 145deb9d82a..93e9b965716 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp @@ -33,7 +33,8 @@ using StabilityData = std::tuple< real64 const, // pressure real64 const, // temperature real64 const, // CH4 mole fraction - real64 const // expected tangent plane distance + bool const, // expected instability status of mixture + real64 const // expected CH4 mole fraction in incipient phase >; template< EquationOfStateType EOS_TYPE > @@ -56,7 +57,8 @@ class StabilityTestTest2CompFixture : public ::testing::TestWithParam< Stabilit real64 const pressure = std::get< 0 >( data ); real64 const temperature = std::get< 1 >( data ); real64 const zCH4 = std::get< 2 >( data ); - real64 const expectedTangentPlaneDistance = std::get< 3 >( data ); + bool const expectedUnstableMixture = std::get< 3 >( data ); + real64 const expectedZCH4 = std::get< 4 >( data ); constitutive::compositional::FlashData flashData; flashData.liquidEos = EOS_TYPE; @@ -66,7 +68,8 @@ class StabilityTestTest2CompFixture : public ::testing::TestWithParam< Stabilit composition[0] = zCH4; composition[1] = 1.0 - zCH4; - real64 tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; + bool unstableMixture = false; + EquationOfStateType incipientEos = EOS_TYPE; stackArray1d< real64, numComps > kValues( numComps ); stackArray1d< real64, numComps > incipientComposition( numComps ); @@ -84,19 +87,23 @@ class StabilityTestTest2CompFixture : public ::testing::TestWithParam< Stabilit temperature, composition.toSliceConst(), componentProperties, - EOS_TYPE, flashData, kValues.toSliceConst(), flashParameters->m_continuousParameters, flashParameters->m_discreteParameters, - tangentPlaneDistance, + unstableMixture, + incipientEos, incipientComposition.toSlice() ); // Expect this to succeed ASSERT_EQ( stabilityStatus, true ); - // Check the tanget plane distance - checkRelativeError( expectedTangentPlaneDistance, tangentPlaneDistance, relTol, absTol ); + // Check the stability labe; + ASSERT_EQ( unstableMixture, expectedUnstableMixture ); + + // Check the incipient methane fraction + real64 const incipientZCH4 = incipientComposition[0]; + checkRelativeError( expectedZCH4, incipientZCH4, relTol, absTol ); } protected: @@ -130,24 +137,28 @@ TEST_P( SoaveRedlichKwong, testStabilityTest ) INSTANTIATE_TEST_SUITE_P(StabilityTest, PengRobinson, ::testing::ValuesIn({ - {1.0e+06, 297.15, 0.400, -2.7755576e-16}, - {1.0e+06, 353.15, 0.400, -1.1102230e-16}, - {5.0e+06, 297.15, 0.400, -1.8937164e-01}, - {5.0e+06, 353.15, 0.400, 1.6653345e-16}, - {2.0e+07, 297.15, 0.400, -1.2767565e-15}, - {2.0e+07, 353.15, 0.400, -1.6653345e-16} + {1.0e+06, 297.15, 0.4000, false, 0.40000000 }, + {1.0e+06, 353.15, 0.4000, false, 0.40000000 }, + {5.0e+06, 297.15, 0.4000, true, 0.78638826 }, + {5.0e+06, 353.15, 0.4000, false, 0.40000000 }, + {2.0e+07, 297.15, 0.4000, false, 0.40000000 }, + {2.0e+07, 353.15, 0.4000, false, 0.40000001 }, + {5.0e+06, 297.15, 0.7860, true, 0.31984391 }, + {5.0e+06, 297.15, 0.7870, true, 0.32331543 }, + {5.0e+06, 297.15, 0.3200, true, 0.78604645 }, + {5.0e+06, 297.15, 0.3220, true, 0.78662927 } }) ); INSTANTIATE_TEST_SUITE_P( StabilityTest, SoaveRedlichKwong, ::testing::ValuesIn({ - {1.0e+06, 297.15, 0.350, -2.7755576e-16}, - {1.0e+06, 353.15, 0.350, -3.8857806e-16}, - {5.0e+06, 297.15, 0.350, -2.0304080e-01}, - {5.0e+06, 353.15, 0.350, -2.7755576e-16}, - {2.0e+07, 297.15, 0.350, -6.6613381e-16}, - {2.0e+07, 353.15, 0.350, -7.7715612e-16} + {1.0e+06, 297.15, 0.3500, false, 0.35000000 }, + {1.0e+06, 353.15, 0.3500, false, 0.35000000 }, + {5.0e+06, 297.15, 0.3500, true, 0.79542990 }, + {5.0e+06, 353.15, 0.3500, false, 0.35000000 }, + {2.0e+07, 297.15, 0.3500, false, 0.35000000 }, + {2.0e+07, 353.15, 0.3500, false, 0.35000000 } }) ); diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp index f72fb49b6a2..07e3ee5bf41 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp @@ -30,20 +30,21 @@ namespace testing { static constexpr integer numComps = 9; +static constexpr integer targetComponent = 8; -using FlashData = std::tuple< +using StabilityData = std::tuple< real64 const, // pressure real64 const, // temperature Feed< numComps > const, // total composition - real64 const // expected tangent plane distance + bool const, // expected instability status of mixture + real64 const // expected mole fraction of targetComponent in incipient phase >; template< EquationOfStateType EOS_TYPE > -class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashData > +class StabilityTestTest9CompFixture : public ::testing::TestWithParam< StabilityData > { static constexpr real64 relTol = 1.0e-5; static constexpr real64 absTol = 1.0e-7; - static constexpr real64 tpdTol = MultiFluidConstants::fugacityTolerance; public: StabilityTestTest9CompFixture() : m_fluid( createFluid() ) @@ -51,7 +52,7 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat ~StabilityTestTest9CompFixture() = default; - void testStability( FlashData const & data ) + void testStability( StabilityData const & data ) { auto componentProperties = this->m_fluid->createKernelWrapper(); @@ -64,9 +65,12 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat stackArray1d< real64, numComps > composition; TestFluid< numComps >::createArray( composition, std::get< 2 >( data )); - real64 const expectedTangentPlaneDistance = std::get< 3 >( data ); + bool const expectedUnstableMixture = std::get< 3 >( data ); + real64 const expectedZTarget = std::get< 4 >( data ); + + bool unstableMixture = false; + EquationOfStateType incipientEos = EOS_TYPE; - real64 tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; stackArray1d< real64, numComps > kValues( numComps ); stackArray1d< real64, numComps > incipientComposition( numComps ); @@ -84,22 +88,26 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat temperature, composition.toSliceConst(), componentProperties, - EOS_TYPE, flashData, kValues.toSliceConst(), flashParameters->m_continuousParameters, flashParameters->m_discreteParameters, - tangentPlaneDistance, + unstableMixture, + incipientEos, incipientComposition.toSlice() ); // Expect this to succeed ASSERT_EQ( stabilityStatus, true ); - // Check the tanget plane distance - checkRelativeError( expectedTangentPlaneDistance, tangentPlaneDistance, relTol, absTol ); + // Check the stability labe; + ASSERT_EQ( unstableMixture, expectedUnstableMixture ); + + // Check the incipient methane fraction + real64 const incipientZTarget = incipientComposition[targetComponent]; + checkRelativeError( expectedZTarget, incipientZTarget, relTol, absTol ); } - void testFlash( FlashData const & data ) + void testFlash( StabilityData const & data ) { auto componentProperties = this->m_fluid->createKernelWrapper(); @@ -112,9 +120,15 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat stackArray1d< real64, numComps > composition; TestFluid< numComps >::createArray( composition, std::get< 2 >( data )); - real64 tangentPlaneDistance = LvArray::NumericLimits< real64 >::max; + bool unstableMixture = false; + EquationOfStateType incipientEos = EOS_TYPE; + + StackArray< real64, 2, 3*numComps > phaseCompositions( 3, numComps ); + real64 vapourFraction = -1.0; stackArray2d< real64, numComps > kValues( 1, numComps ); - stackArray1d< real64, numComps > incipientComposition( numComps ); + arraySlice1d< real64 > liquidComposition = phaseCompositions[0]; + arraySlice1d< real64 > vapourComposition = phaseCompositions[1]; + arraySlice1d< real64 > incipientComposition = phaseCompositions[2]; KValueInitialization::computeWilsonGasLiquidKvalue( numComps, pressure, @@ -130,19 +144,15 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat temperature, composition.toSliceConst(), componentProperties, - EOS_TYPE, flashData, kValues[0].toSliceConst(), flashParameters->m_continuousParameters, flashParameters->m_discreteParameters, - tangentPlaneDistance, - incipientComposition.toSlice() ); + unstableMixture, + incipientEos, + incipientComposition ); // Now perform the nagative flash - real64 vapourFraction = -1.0; - stackArray1d< real64, numComps > liquidComposition( numComps ); - stackArray1d< real64, numComps > vapourComposition( numComps ); - bool const status = NegativeTwoPhaseFlash::compute( numComps, pressure, @@ -154,8 +164,8 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat flashParameters->m_discreteParameters, kValues.toSlice(), vapourFraction, - liquidComposition.toSlice(), - vapourComposition.toSlice() ); + liquidComposition, + vapourComposition ); // Expect this to succeed ASSERT_EQ( status, true ); @@ -165,7 +175,7 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< FlashDat real64 const L = 1.0 - V; // Check stability vs flash - if( tangentPlaneDistance < -tpdTol ) + if( unstableMixture ) { // Unstable mixture: both L and V should be positive ASSERT_GT( V, epsilon ); @@ -235,24 +245,24 @@ TEST_P( SoaveRedlichKwong, testStabilityWithFlash ) INSTANTIATE_TEST_SUITE_P( StabilityTest, PengRobinson, - ::testing::Values( - FlashData(1.0e+05, 2.8815e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -2.668360e+03), - FlashData(1.0e+05, 2.9715e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -1.245873e+03), - FlashData(1.0e+05, 3.5315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -2.881300e+01), - FlashData(1.0e+05, 3.9315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -3.448854e+00), - FlashData(1.0e+05, 5.7315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -2.862294e-16) - ) + ::testing::ValuesIn({ + {1.0e+05, 288.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99992981}, + {1.0e+05, 297.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99989343}, + {1.0e+05, 353.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99906841}, + {1.0e+05, 393.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99685491}, + {1.0e+05, 573.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, false, 0.16920000} + }) ); INSTANTIATE_TEST_SUITE_P( StabilityTest, SoaveRedlichKwong, - ::testing::Values( - FlashData(1.0e+05, 2.8815e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -3.340952e+03), - FlashData(1.0e+05, 2.9715e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -1.523837e+03), - FlashData(1.0e+05, 3.5315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -3.181331e+01), - FlashData(1.0e+05, 3.9315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -3.678230e+00), - FlashData(1.0e+05, 5.7315e+02, {0.00900, 0.00300, 0.53470, 0.11460, 0.08790, 0.04560, 0.02090, 0.01510, 0.16920}, -2.736526e-16) - ) + ::testing::ValuesIn({ + {1.0e+05, 288.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99994255}, + {1.0e+05, 297.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99991141}, + {1.0e+05, 353.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99916193}, + {1.0e+05, 393.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99704625}, + {1.0e+05, 573.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, false, 0.16920000} + }) ); /* UNCRUSTIFY-ON */ From 27e9704ed2cb4704ae1090a03ffab688ff0979db Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 31 Jul 2025 21:50:02 -0500 Subject: [PATCH 16/28] Remove debug code --- .../CompositionalMultiphaseFluidUpdates.hpp | 16 --- .../functions/NegativeTwoPhaseFlash.hpp | 77 +++++------- .../functions/NegativeTwoPhaseFlash_impl.hpp | 111 ++++++------------ 3 files changed, 66 insertions(+), 138 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp index b473d0ba722..6af1f3366dc 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp @@ -408,9 +408,6 @@ update( localIndex const k, real64 const temperature, arraySlice1d< geos::real64 const, compflow::USD_COMP - 1 > const & composition ) const { -// m_kValues[k][q][0][0] = 0.0; -//std::ostringstream os; -//os << "PVT: " << std::setw(2) << k << " "; compute( pressure, temperature, composition, @@ -423,19 +420,6 @@ update( localIndex const k, m_phaseCompFraction( k, q ), m_totalDensity( k, q ), m_kValues[k][q] ); -//os -//<< std::scientific << std::setprecision(5) << std::setw(13) << pressure << " " -//<< std::fixed << std::setprecision(2) << temperature << " " -//<< std::fixed << std::setprecision(5) -//<< composition << " " -//<< m_phaseCompFraction( k, q ).value[0] << " " -//<< m_phaseCompFraction( k, q ).value[1] << " | " -//<< std::scientific << std::setprecision(5) << std::setw(13) << m_phaseFraction( k, q ).value[1] << " | " -//<< std::scientific << std::setprecision(5) << std::setw(13) << m_phaseMassDensity( k, q ).value[0] << " " -//<< std::scientific << std::setprecision(5) << std::setw(13) << m_phaseMassDensity( k, q ).value[1] << " | " -//<< std::scientific << std::setprecision(5) << std::setw(13) << m_totalDensity( k, q ).value << " | " -//<< "\n"; -//std::cout << os.str(); } template< typename FLASH, typename PHASE1, typename PHASE2, typename PHASE3 > diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp index 19dcf465128..1509701600a 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp @@ -38,20 +38,32 @@ struct NegativeTwoPhaseFlash public: /** - * @brief Perform negative two-phase EOS flash - * @param[in] numComps number of components - * @param[in] pressure pressure - * @param[in] temperature temperature - * @param[in] composition composition of the mixture - * @param[in] componentProperties The compositional component properties - * @param[in] flashData The parameters required for the flash - * @param[in] continuousFlashParameters List of continuous (float) parameters for flash - * @param[in] discreteFlashParameters List of discrete (integer) parameters for flash - * @param[in/out] kValues The phase equilibrium ratios - * @param[out] vapourPhaseMoleFraction the calculated vapour (gas) mole fraction - * @param[out] liquidComposition the calculated liquid phase composition - * @param[out] vapourComposition the calculated vapour phase composition - * @return an indicator of success of the flash + * @brief Perform a two-phase EOS flash calculation. + * + * @details + * Executes a negative flash calculation using an equation of state (EOS) model + * to determine the equilibrium phase split of a multicomponent mixture at a given + * pressure and temperature. The function computes the vapor phase mole fraction, + * as well as the compositions of the vapor and liquid phases, based on the provided + * initial estimates and component properties. Uses successive substitution. + * + * @tparam USD1 Unique stride descriptor for the K-values array. + * @tparam USD2 Unique stride descriptor for the phase composition arrays. + * + * @param[in] numComps Number of components in the mixture. + * @param[in] pressure System pressure [Pa]. + * @param[in] temperature System temperature [K]. + * @param[in] composition Overall composition of the mixture (z_i). + * @param[in] componentProperties Thermodynamic properties of each component. + * @param[in] flashData Precomputed data and parameters required for the flash calculation. + * @param[in] continuousFlashParameters List of continuous (floating-point) parameters for the flash. + * @param[in] discreteFlashParameters List of discrete (integer) parameters for the flash. + * @param[in,out] kValues Phase equilibrium ratios (K-values), updated during the flash. + * @param[out] vapourPhaseMoleFraction Calculated vapor phase mole fraction (V). + * @param[out] liquidComposition Calculated composition of the liquid phase (x_i). + * @param[out] vapourComposition Calculated composition of the vapor phase (y_i). + * + * @return True if the flash calculation was successful; false otherwise. */ template< int USD1, int USD2 > GEOS_HOST_DEVICE @@ -99,42 +111,6 @@ struct NegativeTwoPhaseFlash arraySlice2d< real64, USD3 > const & vapourCompositionDerivs ); private: - /** - * @brief Calculate the logarithms of the fugacity ratios - * @param[in] numComps number of components - * @param[in] pressure pressure - * @param[in] temperature temperature - * @param[in] composition composition of the mixture - * @param[in] componentProperties The compositional component properties - * @param[in] flashData The parameters required for the flash - * @param[in] kValues The k-values - * @param[in] presentComponents The indices of the present components - * @param[out] vapourPhaseMoleFraction the calculated vapour (gas) mole fraction - * @param[out] liquidComposition the calculated liquid phase composition - * @param[out] vapourComposition the calculated vapour phase composition - * @param[out] logLiquidFugacity the calculated log fugacity ratios for the liquid phase - * @param[out] logVapourFugacity the calculated log fugacity ratios for the vapour phase - * @param[out] fugacityRatios the fugacity rations - * @return The error - */ - template< integer USD1, integer USD2 > - GEOS_HOST_DEVICE - static real64 computeFugacityRatio( - integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - arraySlice1d< real64 const, USD1 > const & kValues, - arraySlice1d< integer const > const & presentComponents, - real64 & vapourPhaseMoleFraction, - arraySlice1d< real64, USD2 > const & liquidComposition, - arraySlice1d< real64, USD2 > const & vapourComposition, - arraySlice1d< real64 > const & logLiquidFugacity, - arraySlice1d< real64 > const & logVapourFugacity, - arraySlice1d< real64 > const & fugacityRatios ); - /** * @brief Calculate the derivatives of the flash. * @@ -186,6 +162,7 @@ struct NegativeTwoPhaseFlash * @return @c true if truncation should be applied */ template< integer USD1, integer USD2 > + GEOS_FORCE_INLINE GEOS_HOST_DEVICE static bool truncateCompositions( integer const numComps, arraySlice1d< real64 const, USD1 > const & totalComposition, diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index b7f5ba9058f..b1b367feaa9 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -77,20 +77,44 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, bool converged = false; for( localIndex iterationCount = 0; iterationCount < maxIterations; ++iterationCount ) { - real64 const error = computeFugacityRatio( numComps, - pressure, - temperature, - composition, - componentProperties, - flashData, - kVapourLiquid.toSliceConst(), - presentComponents, - vapourPhaseMoleFraction, - liquidComposition, - vapourComposition, - logLiquidFugacity, - logVapourFugacity, - fugacityRatios ); + // Solve Rachford-Rice Equation + vapourPhaseMoleFraction = RachfordRice::solve( kVapourLiquid.toSliceConst(), composition, presentComponents ); + + // Assign phase compositions + for( integer ic = 0; ic < numComps; ++ic ) + { + liquidComposition[ic] = composition[ic] / ( 1.0 + vapourPhaseMoleFraction * ( kVapourLiquid[ic] - 1.0 ) ); + vapourComposition[ic] = kVapourLiquid[ic] * liquidComposition[ic]; + } + + normalizeComposition( numComps, liquidComposition ); + normalizeComposition( numComps, vapourComposition ); + + FugacityCalculator::computeLogFugacity( numComps, + pressure, + temperature, + liquidComposition.toSliceConst(), + componentProperties, + flashData.liquidEos, + flashData, + logLiquidFugacity ); + FugacityCalculator::computeLogFugacity( numComps, + pressure, + temperature, + vapourComposition.toSliceConst(), + componentProperties, + flashData.vapourEos, + flashData, + logVapourFugacity ); + + // Compute fugacity ratios and calculate the error + real64 error = 0.0; + for( integer const ic : presentComponents ) + { + fugacityRatios[ic] = ( logLiquidFugacity[ic] - logVapourFugacity[ic] ) + log( liquidComposition[ic] ) - log( vapourComposition[ic] ); + error += (fugacityRatios[ic]*fugacityRatios[ic]); + } + error = LvArray::math::sqrt( error ); // Compute fugacity ratios and check convergence converged = (error < flashTolerance); @@ -373,64 +397,7 @@ void NegativeTwoPhaseFlash::computeDerivatives( } template< integer USD1, integer USD2 > -GEOS_HOST_DEVICE -real64 NegativeTwoPhaseFlash::computeFugacityRatio( - integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - arraySlice1d< real64 const, USD1 > const & kValues, - arraySlice1d< integer const > const & presentComponents, - real64 & vapourPhaseMoleFraction, - arraySlice1d< real64, USD2 > const & liquidComposition, - arraySlice1d< real64, USD2 > const & vapourComposition, - arraySlice1d< real64 > const & logLiquidFugacity, - arraySlice1d< real64 > const & logVapourFugacity, - arraySlice1d< real64 > const & fugacityRatios ) -{ - // Solve Rachford-Rice Equation - vapourPhaseMoleFraction = RachfordRice::solve( kValues, composition, presentComponents ); - - // Assign phase compositions - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidComposition[ic] = composition[ic] / ( 1.0 + vapourPhaseMoleFraction * ( kValues[ic] - 1.0 ) ); - vapourComposition[ic] = kValues[ic] * liquidComposition[ic]; - } - - normalizeComposition( numComps, liquidComposition ); - normalizeComposition( numComps, vapourComposition ); - - FugacityCalculator::computeLogFugacity( numComps, - pressure, - temperature, - liquidComposition.toSliceConst(), - componentProperties, - flashData.liquidEos, - flashData, - logLiquidFugacity ); - FugacityCalculator::computeLogFugacity( numComps, - pressure, - temperature, - vapourComposition.toSliceConst(), - componentProperties, - flashData.vapourEos, - flashData, - logVapourFugacity ); - - // Compute fugacity ratios and calculate the error - real64 error = 0.0; - for( integer const ic : presentComponents ) - { - fugacityRatios[ic] = ( logLiquidFugacity[ic] - logVapourFugacity[ic] ) + log( liquidComposition[ic] ) - log( vapourComposition[ic] ); - error += (fugacityRatios[ic]*fugacityRatios[ic]); - } - return LvArray::math::sqrt( error ); -} - -template< integer USD1, integer USD2 > +GEOS_FORCE_INLINE GEOS_HOST_DEVICE bool NegativeTwoPhaseFlash::truncateCompositions( integer const numComps, arraySlice1d< real64 const, USD1 > const & totalComposition, From 9df03b9693105f40a3fdc0824c7564651158a930 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 31 Jul 2025 22:00:22 -0500 Subject: [PATCH 17/28] Fix unit test --- .../constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp index 93d977b2a32..00a60a52b7a 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp @@ -464,7 +464,7 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlash, SoaveRedlichKwong, ::testing::Values( - FlashData( 1.000000e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000197, {0.000361, 0.839175}, {0.010852, 0.000016} )/**, + FlashData( 1.000000e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000197, {0.000361, 0.839175}, {0.010852, 0.000016} ), FlashData( 1.000000e+05, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.798097, {0.000372, 0.837963}, {0.011183, 0.000016} ), FlashData( 1.000000e+05, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998678, {0.000233, 0.937435}, {0.007035, 0.000017} ), FlashData( 1.013250e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000102, {0.000362, 0.839096}, {0.010741, 0.000015} ), @@ -568,7 +568,7 @@ INSTANTIATE_TEST_SUITE_P( FlashData( 1.500000e+07, 5.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.986509, {0.007097, 0.343039}, {0.009026, 0.166823} ), FlashData( 1.000000e+08, 8.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), FlashData( 1.000000e+08, 8.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), - FlashData( 1.000000e+08, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ) */ + FlashData( 1.000000e+08, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ) ) ); From 0f5e905621977d5785835f7528a7fe3ab1c2b261 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Fri, 1 Aug 2025 09:34:37 -0500 Subject: [PATCH 18/28] Remove debug code --- .../compositional/functions/NegativeTwoPhaseFlash_impl.hpp | 4 ---- .../multifluid/compositional/functions/StabilityTest.hpp | 5 ----- 2 files changed, 9 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index b1b367feaa9..f251d632117 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -49,8 +49,6 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, arraySlice1d< real64, USD2 > const & liquidComposition, arraySlice1d< real64, USD2 > const & vapourComposition ) { - GEOS_MARK_FUNCTION; - constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; StackArray< real64, 2, 3*maxNumComps > workSpace( 3, maxNumComps ); arraySlice1d< real64 > logLiquidFugacity = workSpace[0]; @@ -166,8 +164,6 @@ void NegativeTwoPhaseFlash::computeDerivatives( arraySlice2d< real64, USD3 > const & liquidCompositionDerivs, arraySlice2d< real64, USD3 > const & vapourCompositionDerivs ) { - GEOS_MARK_FUNCTION; - constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; constexpr integer maxNumDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp index 5959dd51abd..3e017c005ea 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp @@ -28,7 +28,6 @@ #include "constitutive/fluid/multifluid/compositional/parameters/ComponentProperties.hpp" #include "constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp" #include "constitutive/fluid/multifluid/compositional/functions/FlashData.hpp" -#include "common/TimingMacros.hpp" namespace geos { @@ -78,8 +77,6 @@ struct StabilityTest EquationOfStateType & incipientEquationOfState, arraySlice1d< real64 > const & incipientComposition ) { - GEOS_MARK_FUNCTION; - stackArray2d< real64, 4*maxNumComps > workSpace( 4, numComps ); arraySlice1d< real64 > logFugacity = workSpace[0]; arraySlice1d< real64 > normalizedComposition = workSpace[1]; @@ -260,8 +257,6 @@ struct StabilityTest arraySlice2d< real64, USD2 > const & incipientCompositionDerivs, arraySlice2d< real64, USD2 > const & compositionDerivs ) { - GEOS_MARK_FUNCTION; - integer constexpr maxNumRows = MultiFluidConstants::MAX_NUM_COMPONENTS + 1; integer constexpr maxDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; From 2607cbc812537f130bdbd9e5841ec3b6c117eda3 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Fri, 1 Aug 2025 10:48:07 -0500 Subject: [PATCH 19/28] Update PVT driver test --- .../testPVT_ThreePhaseCompositional_blackOil.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreComponents/unitTests/constitutiveTests/testPVT_ThreePhaseCompositional_blackOil.txt b/src/coreComponents/unitTests/constitutiveTests/testPVT_ThreePhaseCompositional_blackOil.txt index 6bf59be5458..a43502c8289 100644 --- a/src/coreComponents/unitTests/constitutiveTests/testPVT_ThreePhaseCompositional_blackOil.txt +++ b/src/coreComponents/unitTests/constitutiveTests/testPVT_ThreePhaseCompositional_blackOil.txt @@ -59,10 +59,10 @@ 9.2000e-01 1.6840e+06 5.5315e+02 5.9765e+01 6.8961e-07 5.7850e-01 3.0879e-01 1.1271e-01 5.5841e+02 1.9813e+01 1.0116e+03 5.5841e+02 1.9813e+01 1.0116e+03 1.0788e-04 1.4097e-05 3.2929e-04 3.8354e-02 9.6165e-01 0.0000e+00 7.7004e-01 2.2996e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 9.4000e-01 1.2880e+06 5.5315e+02 4.3168e+01 9.8725e-07 4.8744e-01 3.9985e-01 1.1271e-01 5.5968e+02 1.8025e+01 1.0115e+03 5.5968e+02 1.8025e+01 1.0115e+03 1.0818e-04 1.3437e-05 3.2929e-04 2.7415e-02 9.7259e-01 0.0000e+00 7.1015e-01 2.8985e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 9.6000e-01 8.9200e+05 5.5315e+02 2.6004e+01 1.6952e-06 2.7229e-01 6.1500e-01 1.1271e-01 5.6094e+02 1.6244e+01 1.0113e+03 5.6094e+02 1.6244e+01 1.0113e+03 1.0845e-04 1.2477e-05 3.2929e-04 1.6340e-02 9.8366e-01 0.0000e+00 5.9920e-01 4.0080e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 - 9.8000e-01 4.9600e+05 5.5315e+02 1.2066e+01 2.1188e-06 8.8729e-01 0.0000e+00 1.1271e-01 1.0720e+01 1.0720e+01 1.0112e+03 1.0720e+01 1.0720e+01 1.0112e+03 1.1716e-05 1.1716e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 9.8000e-01 4.9600e+05 5.5315e+02 1.2066e+01 2.1188e-06 0.0000e+00 8.8729e-01 1.1271e-01 1.0720e+01 1.0720e+01 1.0112e+03 1.0720e+01 1.0720e+01 1.0112e+03 1.1716e-05 1.1716e-05 3.2929e-04 9.1515e-01 8.4850e-02 0.0000e+00 5.0000e-01 5.0000e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 1.0000e+00 1.0000e+05 5.5315e+02 2.3385e+00 1.0097e-05 8.8729e-01 0.0000e+00 1.1271e-01 2.0755e+00 2.0755e+00 1.0110e+03 2.0755e+00 2.0755e+00 1.0110e+03 1.1560e-05 1.1560e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 1.0200e+00 4.9600e+05 5.8315e+02 1.1342e+01 2.0987e-06 8.8729e-01 0.0000e+00 1.1271e-01 1.0076e+01 1.0076e+01 1.0112e+03 1.0076e+01 1.0076e+01 1.0112e+03 1.2221e-05 1.2221e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 - 1.0400e+00 8.9200e+05 5.8315e+02 2.1089e+01 1.2070e-06 8.8729e-01 0.0000e+00 1.1271e-01 1.8756e+01 1.8756e+01 1.0113e+03 1.8756e+01 1.8756e+01 1.0113e+03 1.2405e-05 1.2405e-05 3.2929e-04 5.0000e-01 5.0000e-01 0.0000e+00 9.1515e-01 8.4850e-02 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 + 1.0400e+00 8.9200e+05 5.8315e+02 2.1089e+01 1.2070e-06 0.0000e+00 8.8729e-01 1.1271e-01 1.8756e+01 1.8756e+01 1.0113e+03 1.8756e+01 1.8756e+01 1.0113e+03 1.2405e-05 1.2405e-05 3.2929e-04 9.1515e-01 8.4850e-02 0.0000e+00 5.0000e-01 5.0000e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 1.0600e+00 1.2880e+06 5.8315e+02 3.2115e+01 1.2866e-06 4.3627e-02 8.4366e-01 1.1271e-01 5.1804e+02 2.7265e+01 1.0115e+03 5.1804e+02 2.7265e+01 1.0115e+03 8.2939e-05 1.2695e-05 3.2929e-04 2.4366e-02 9.7563e-01 0.0000e+00 5.1344e-01 4.8656e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 1.0800e+00 1.6840e+06 5.8315e+02 4.8218e+01 8.2999e-07 3.0186e-01 5.8543e-01 1.1271e-01 5.1649e+02 2.9209e+01 1.0116e+03 5.1649e+02 2.9209e+01 1.0116e+03 8.2756e-05 1.3409e-05 3.2929e-04 3.6932e-02 9.6307e-01 0.0000e+00 6.1026e-01 3.8974e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 1.1000e+00 2.0800e+06 5.8315e+02 6.3818e+01 6.0757e-07 4.2838e-01 4.5891e-01 1.1271e-01 5.1495e+02 3.1163e+01 1.0118e+03 5.1495e+02 3.1163e+01 1.0118e+03 8.2556e-05 1.3965e-05 3.2929e-04 4.9339e-02 9.5066e-01 0.0000e+00 6.7192e-01 3.2808e-01 0.0000e+00 0.0000e+00 0.0000e+00 1.0000e+00 From b268f8ef41199232d6ad57387cf8e51582ecdd6c Mon Sep 17 00:00:00 2001 From: dkachuma Date: Fri, 1 Aug 2025 13:23:45 -0500 Subject: [PATCH 20/28] Update unit test --- .../models/NegativeTwoPhaseFlashModel.hpp | 35 ++-- .../testNegativeTwoPhaseFlashModel.cpp | 151 +++++++++--------- 2 files changed, 84 insertions(+), 102 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp index a5f5ff7e9c9..329c2760277 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp @@ -116,18 +116,18 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate if( 0 < stabilityIterations || needInitialisation ) { - stabilityStatus = StabilityTest::compute( m_numComponents, - pressure, - temperature, - compFraction, - componentProperties, - m_flashData, - kVapourLiquid.toSliceConst(), - m_continuousFlashParameters.toSliceConst(), - m_discreteFlashParameters.toSliceConst(), - unstableMixture, - incipientEquationOfState, - incipientComposition.toSlice() ); + stabilityStatus = StabilityTest::compute( m_numComponents, + pressure, + temperature, + compFraction, + componentProperties, + m_flashData, + kVapourLiquid.toSliceConst(), + m_continuousFlashParameters.toSliceConst(), + m_discreteFlashParameters.toSliceConst(), + unstableMixture, + incipientEquationOfState, + incipientComposition.toSlice() ); } // If the stability test failed to converge to a stationary point then we will assume the mixture is unstable @@ -246,17 +246,6 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate { phaseFraction.derivs[m_liquidIndex][ic] = -phaseFraction.derivs[m_vapourIndex][ic]; } -//std::cout -//<< "PVT(2) " << unstableMixture << " " -//<< std::fixed << std::setprecision(6) << phaseFraction.value[m_vapourIndex] << " " -//<< std::scientific << std::setprecision(4) << kVapourLiquid << "\n" -//<< std::fixed << std::setprecision(6) -//<< " G " << incipientComposition.toSliceConst() << "\n" -//<< " Z " << compFraction.toSliceConst() << "\n" -//<< " X " << phaseCompFraction.value[0].toSliceConst() << "\n" -//<< " Y " << phaseCompFraction.value[1].toSliceConst() << "\n" -//<< "----------------------------------------------------------------------" -//<<"\n"; } template< int USD > diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp index 3225c7b959d..cd051c5e38d 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp @@ -174,7 +174,6 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< PhasePropSlice( phaseFraction, dPhaseFraction ), PhaseCompSlice( phaseComponentFraction, dPhaseComponentFraction ) ); - return; for( integer ip = 0; ip < numPhases; ip++ ) { checkRelativeError( phaseFraction[ip], expectedPhaseFraction[ip], relTol, absTol ); @@ -331,51 +330,47 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< }; using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; -//using SoaveRedlichKwong2 = NegativeTwoPhaseFlashModelTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; -//using SoreideWhitson4 = NegativeTwoPhaseFlashModelTestFixture< 4, EquationOfStateType::SoreideWhitson >; +using SoaveRedlichKwong2 = NegativeTwoPhaseFlashModelTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; +using SoreideWhitson4 = NegativeTwoPhaseFlashModelTestFixture< 4, EquationOfStateType::SoreideWhitson >; TEST_P( PengRobinson9, testFlash ) { testFlash( GetParam() ); -// testFlashDerivatives( GetParam() ); } -/* - TEST_P( SoaveRedlichKwong2, testFlash ) - { - //testFlash( GetParam() ); - } - TEST_P( SoreideWhitson4, testFlash ) - { - //testFlash( GetParam() ); - testFlashDerivatives( GetParam() ); - } - - TEST_P( PengRobinson9, testFlashDerivatives ) - { - auto const param = GetParam(); - setStabilityThreshold( -1.0e-8 ); - testFlashDerivatives( param ); - setStabilityThreshold( 1.0e-8 ); - testFlashDerivatives( param ); - } - TEST_P( SoaveRedlichKwong2, testFlashDerivatives ) - { - auto const param = GetParam(); - setStabilityThreshold( -1.0e-8 ); - testFlashDerivatives( param ); - setStabilityThreshold( 1.0e-8 ); - testFlashDerivatives( param ); - } - TEST_P( SoreideWhitson4, testFlashDerivatives ) - { - auto const param = GetParam(); - setStabilityThreshold( -1.0e-8 ); - setStabilityThreshold( -1.0e-6 ); - testFlashDerivatives( param ); - setStabilityThreshold( 1.0e-8 ); - testFlashDerivatives( param ); - } - */ +TEST_P( SoaveRedlichKwong2, testFlash ) +{ + testFlash( GetParam() ); +} +TEST_P( SoreideWhitson4, testFlash ) +{ + testFlash( GetParam() ); +} + +TEST_P( PengRobinson9, testFlashDerivatives ) +{ + auto const param = GetParam(); + setStabilityThreshold( -1.0e-8 ); + testFlashDerivatives( param ); + setStabilityThreshold( 1.0e-8 ); + testFlashDerivatives( param ); +} +TEST_P( SoaveRedlichKwong2, testFlashDerivatives ) +{ + auto const param = GetParam(); + setStabilityThreshold( -1.0e-8 ); + testFlashDerivatives( param ); + setStabilityThreshold( 1.0e-8 ); + testFlashDerivatives( param ); +} +TEST_P( SoreideWhitson4, testFlashDerivatives ) +{ + auto const param = GetParam(); + setStabilityThreshold( -1.0e-8 ); + testFlashDerivatives( param ); + setStabilityThreshold( 1.0e-8 ); + testFlashDerivatives( param ); +} + //------------------------------------------------------------------------------- // Data //------------------------------------------------------------------------------- @@ -385,57 +380,55 @@ TEST_P( PengRobinson9, testFlash ) INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, PengRobinson9, ::testing::ValuesIn>({ - //{1.0e+07, 293.15, { 0.10900000, 0.00300000, 0.23470000, 0.11460000, 0.08790000, 0.04560000, 0.02090000, 0.01510000, 0.36920000 }, 0.78697508, 0.21302492, { 0.13701652, 0.08659405, 0.46883838 }, { 0.00549895, 0.21806200, 0.00110727 }}, - //{1.0e+07, 333.15, { 0.00549900, 0.00222500, 0.69884300, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110000 }, 0.00000000, 1.00000000, { 0.00549901, 0.21806223, 0.00110000 }, { 0.00549900, 0.21806200, 0.00110000 }}, - //{1.0e+07, 298.15, { 0.00549900, 0.00222500, 0.69883600, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110700 }, 0.00000000, 1.00000000, { 0.11827726, 0.08574692, 0.49905345 }, { 0.00549900, 0.21806200, 0.00110700 }}, - {1.0e+07, 288.15, { 0.00549900, 0.00222500, 0.69883600, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110700 }, 0.00054604, 0.99945396, { 0.16138581, 0.08705737, 0.43336991 }, { 0.00541384, 0.21813379, 0.00087084 }} - //{1.0e+07, 288.00, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 1.00000000, 0.00000000, { 0.13701652, 0.08659405, 0.46883834 }, { 0.00477313, 0.21542401, 0.00091472 }}, - //{1.0e+07, 293.00, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 1.00000000, 0.00000000, { 0.13701652, 0.08659405, 0.46883834 }, { 0.00547668, 0.21798697, 0.00110119 }}, - //{1.0e+07, 293.15, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 0.99999993, 0.00000007, { 0.13701653, 0.08659404, 0.46883837 }, { 0.00549895, 0.21806197, 0.00110727 }} + {1.00000e+07, 293.15, { 0.10900000, 0.00300000, 0.23470000, 0.11460000, 0.08790000, 0.04560000, 0.02090000, 0.01510000, 0.36920000 }, 0.78697508, 0.21302492, { 0.13701652, 0.08659405, 0.46883838 }, { 0.00549895, 0.21806200, 0.00110727 }}, + {1.00000e+07, 333.15, { 0.00549900, 0.00222500, 0.69884300, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110000 }, 0.00000000, 1.00000000, { 0.00549901, 0.21806223, 0.00110000 }, { 0.00549900, 0.21806200, 0.00110000 }}, + {1.00000e+07, 298.15, { 0.00549900, 0.00222500, 0.69883600, 0.21806200, 0.05952600, 0.01200000, 0.00213100, 0.00061300, 0.00110700 }, 0.00000000, 1.00000000, { 0.00549900, 0.21806200, 0.00110700 }, { 0.00549900, 0.21806200, 0.00110700 }}, + {1.00000e+07, 288.00, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 1.00000000, 0.00000000, { 0.13701652, 0.08659405, 0.46883834 }, { 0.13701652, 0.08659405, 0.46883834 }}, + {1.00000e+07, 293.00, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 1.00000000, 0.00000000, { 0.13701652, 0.08659405, 0.46883834 }, { 0.13701652, 0.08659405, 0.46883834 }}, + {1.00000e+07, 293.15, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 0.99999993, 0.00000007, { 0.13701653, 0.08659404, 0.46883837 }, { 0.00549895, 0.21806197, 0.00110727 }} }) ); -/* + INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoreideWhitson4, ::testing::ValuesIn>({ - //{2.01675e+07, 349.150, { 1.14935e-13, 0.00180029, 0.000730624, 0.997469 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, - //{1.07250e+07, 349.150, { 0.42400, 0.05624, 0.05624, 0.46351 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, - //{1.06611e+07, 349.150, { 0.42341, 0.05616, 0.05616, 0.46426 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, - //{1.92943e+07, 349.150, { 0.62210, 0.08283, 0.08283, 0.21224 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, - //{2.00000e+07, 349.150, { 0.75000, 0.10000, 0.10000, 0.05000 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, - {2.00405e+07, 349.150, { 0.8, 0.1, 0.1, 4.81153e-09 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }} - //{1.9995311667610e+07, 349.150, { 0.963345, 0.012672, 0.012665, 0.011317 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, - //{1.9997125998754e+07, 349.150, { 0.963291, 0.012672, 0.012665, 0.011373 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, - //{1.0e+07, 293.15, { 0.75000000, 0.05000000, 0.05000000, 0.15000000 }, 0.15017829, 0.84982171, { 0.00143968, 0.00165781, 0.99682944 }, { 0.88228364, 0.05854291, 0.00035050 }}, - //{1.0e+07, 288.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.88776183, 0.05226933, 0.00025588 }}, - //{1.0e+07, 293.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99999974, 0.00000026, { 0.00143978, 0.00165799, 0.99682925 }, { 0.88234276, 0.05854960, 0.00035050 }}, - //{1.0e+07, 353.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99948528, 0.00051472, { 0.00101790, 0.00159761, 0.99733896 }, { 0.82107330, 0.11891905, 0.00658930 }}, - //{1.0e+07, 278.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00021799, 0.99978201, { 0.00172945, 0.00245159, 0.99572855 }, { 0.88247599, 0.05855523, 0.00013297 }}, - //{1.0e+07, 293.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.00143967, 0.00165782, 0.99682944 }, { 0.88228400, 0.05854300, 0.00035000 }}, - //{1.0e+07, 303.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.00827139, 0.00829367, 0.98303168 }, { 0.88228400, 0.05854300, 0.00035000 }}, - //{1.0e+07, 293.15, { 0.00000000, 0.00000500, 0.00000000, 0.99999500 }, 1.00000000, 0.00000000, { 0.00000000, 0.00000500, 0.99999500 }, { 0.00000000, 0.00000500, 0.99999500 }}, - //{1.0e+07, 293.15, { 0.00000000, 0.02572500, 0.00000000, 0.97427500 }, 1.00000000, 0.00000000, { 0.00000000, 0.02572500, 0.97427500 }, { 0.00000000, 0.99724814, 0.00275186 }}, - //{1.0e+07, 293.15, { 0.00000000, 0.02572600, 0.00000000, 0.97427400 }, 0.99999969, 0.00000031, { 0.00000000, 0.02572570, 0.97427430 }, { 0.00000000, 0.99724814, 0.00275186 }}, - //{1.0e+07, 293.15, { 0.99999500, 0.00000000, 0.00000000, 0.00000500 }, 0.00000000, 1.00000000, { 0.99999500, 0.00000000, 0.00000500 }, { 0.99999500, 0.00000000, 0.00000500 }}, - //{1.0e+07, 288.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00008980, 0.99991020, { 0.00168896, 0.00000000, 0.99831104 }, { 0.99975363, 0.00000000, 0.00024637 }}, - //{1.0e+07, 293.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.00160175, 0.00000000, 0.99839825 }, { 0.99966400, 0.00000000, 0.00033600 }}, - //{1.0e+07, 303.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.00883712, 0.00000000, 0.99116288 }, { 0.99966400, 0.00000000, 0.00033600 }} + {2.01675e+07, 349.15, { 0.00000000, 0.00180029, 0.00073062, 0.99746900 }, 1.00000000, 0.00000000, { 0.00000000, 0.00180029, 0.99746900 }, { 0.00000000, 0.00180029, 0.99746900 }}, + {1.07250e+07, 349.15, { 0.42400000, 0.05624000, 0.05624000, 0.46351000 }, 0.46391991, 0.53608009, { 0.00109926, 0.00153071, 0.99250187 }, { 0.78998321, 0.10358608, 0.00573284 }}, + {1.06611e+07, 349.15, { 0.42341000, 0.05616000, 0.05616000, 0.46426000 }, 0.46465757, 0.53534243, { 0.00109380, 0.00152509, 0.99252663 }, { 0.78997286, 0.10358214, 0.00575264 }}, + {1.92943e+07, 349.15, { 0.62210000, 0.08283000, 0.08283000, 0.21224000 }, 0.21083142, 0.78916858, { 0.00172629, 0.00206379, 0.99021290 }, { 0.78783679, 0.10440721, 0.00439958 }}, + {2.00000e+07, 349.15, { 0.75000000, 0.10000000, 0.10000000, 0.05000000 }, 0.04630725, 0.95369275, { 0.00176884, 0.00209963, 0.99002996 }, { 0.78633091, 0.10475362, 0.00435616 }}, + {1.99953e+07, 349.15, { 0.96334500, 0.01267200, 0.01266500, 0.01131700 }, 0.00782092, 0.99217908, { 0.00199275, 0.00025091, 0.99699415 }, { 0.97092389, 0.01276992, 0.00354735 }}, + {1.99971e+07, 349.15, { 0.96329100, 0.01267200, 0.01266500, 0.01137300 }, 0.00787742, 0.99212258, { 0.00199287, 0.00025093, 0.99699395 }, { 0.97092271, 0.01277061, 0.00354719 }}, + {1.00000e+07, 293.15, { 0.75000000, 0.05000000, 0.05000000, 0.15000000 }, 0.15072066, 0.84927934, { 0.00150781, 0.00166788, 0.99309883 }, { 0.88283407, 0.05857745, 0.00037619 }}, + {1.00000e+07, 288.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.00144000, 0.00165800, 0.99682900 }}, + {1.00000e+07, 293.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.00144000, 0.00165800, 0.99682900 }}, + {1.00000e+07, 353.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99958936, 0.00041064, { 0.00108254, 0.00160931, 0.99723579 }, { 0.87159649, 0.12018752, 0.00661262 }}, + {1.00000e+07, 278.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00020630, 0.99979370, { 0.00181934, 0.00244237, 0.99161209 }, { 0.88246568, 0.05855458, 0.00014546 }}, + {1.00000e+07, 293.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.88228400, 0.05854300, 0.00035000 }, { 0.88228400, 0.05854300, 0.00035000 }}, + {1.00000e+07, 303.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.88228400, 0.05854300, 0.00035000 }, { 0.88228400, 0.05854300, 0.00035000 }}, + {1.00000e+07, 293.15, { 0.00000000, 0.00000500, 0.00000000, 0.99999500 }, 1.00000000, 0.00000000, { 0.00000000, 0.00000500, 0.99999500 }, { 0.00000000, 0.00071931, 0.99928069 }}, + {1.00000e+07, 293.15, { 0.00000000, 0.02572500, 0.00000000, 0.97427500 }, 1.00000000, 0.00000000, { 0.00000000, 0.02572500, 0.97427500 }, { 0.00000000, 0.02572500, 0.97427500 }}, + {1.00000e+07, 293.15, { 0.00000000, 0.02572600, 0.00000000, 0.97427400 }, 0.99999969, 0.00000031, { 0.00000000, 0.02572570, 0.97427430 }, { 0.00000000, 0.99724814, 0.00275186 }}, + {1.00000e+07, 293.15, { 0.99999500, 0.00000000, 0.00000000, 0.00000500 }, 0.00000000, 1.00000000, { 0.99999500, 0.00000000, 0.00000500 }, { 0.99999500, 0.00000000, 0.00000500 }}, + {1.00000e+07, 288.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00008980, 0.99991020, { 0.00168896, 0.00000000, 0.99831104 }, { 0.99975363, 0.00000000, 0.00024637 }}, + {1.00000e+07, 293.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.99966400, 0.00000000, 0.00033600 }, { 0.99966400, 0.00000000, 0.00033600 }}, + {1.00000e+07, 303.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.99966400, 0.00000000, 0.00033600 }, { 0.99966400, 0.00000000, 0.00033600 }} }) ); INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoaveRedlichKwong2, ::testing::ValuesIn>({ - {1.0e+07, 293.15, { 0.75000000, 0.25000000 }, 0.26178317, 0.73821683, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }}, - {1.0e+07, 293.15, { 0.08178000, 0.91822000 }, 0.99999943, 0.00000057, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }}, - {1.0e+07, 293.15, { 0.08177900, 0.91822100 }, 1.00000000, 0.00000000, { 0.08177900, 0.91822100, 0.91822100 }, { 0.98696132, 0.01303868, 0.01303868 }}, - {1.0e+07, 293.15, { 0.08177800, 0.91822200 }, 1.00000000, 0.00000000, { 0.08177800, 0.91822200, 0.91822200 }, { 0.98696116, 0.01303884, 0.01303884 }}, - {1.0e+07, 293.15, { 0.98696200, 0.01303800 }, 0.00000000, 1.00000000, { 0.08178332, 0.91821668, 0.91821668 }, { 0.98696200, 0.01303800, 0.01303800 }}, - {1.0e+07, 293.15, { 0.98696100, 0.01303900 }, 0.00000044, 0.99999956, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }}, - {1.0e+07, 293.15, { 0.98696000, 0.01304000 }, 0.00000154, 0.99999846, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }} + {1.00000e+07, 293.15, { 0.75000000, 0.25000000 }, 0.26178317, 0.73821683, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }}, + {1.00000e+07, 293.15, { 0.08178000, 0.91822000 }, 0.99999943, 0.00000057, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }}, + {1.00000e+07, 293.15, { 0.08177900, 0.91822100 }, 1.00000000, 0.00000000, { 0.08177900, 0.91822100, 0.91822100 }, { 0.08177900, 0.91822100, 0.91822100 }}, + {1.00000e+07, 293.15, { 0.08177800, 0.91822200 }, 1.00000000, 0.00000000, { 0.08177800, 0.91822200, 0.91822200 }, { 0.08177800, 0.91822200, 0.91822200 }}, + {1.00000e+07, 293.15, { 0.98696200, 0.01303800 }, 0.00000000, 1.00000000, { 0.98696200, 0.01303800, 0.01303800 }, { 0.98696200, 0.01303800, 0.01303800 }}, + {1.00000e+07, 293.15, { 0.98696100, 0.01303900 }, 0.00000044, 0.99999956, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }}, + {1.00000e+07, 293.15, { 0.98696000, 0.01304000 }, 0.00000154, 0.99999846, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }} }) ); -*/ + /* UNCRUSTIFY-ON */ } // testing From 0696f56c0e042de7ed9c67f1c90f0dad3b93424b Mon Sep 17 00:00:00 2001 From: dkachuma Date: Tue, 5 Aug 2025 11:13:34 -0500 Subject: [PATCH 21/28] Split stability test file --- .../constitutive/CMakeLists.txt | 1 + .../functions/NegativeTwoPhaseFlash.hpp | 35 ++ .../functions/NegativeTwoPhaseFlash_impl.hpp | 506 ++++++++++++++++++ .../compositional/functions/StabilityTest.hpp | 189 ++----- .../functions/StabilityTest_impl.hpp | 373 +++++++++++++ .../compositional/functions/Utilities.hpp | 21 + .../parameters/FlashParameters.cpp | 10 + .../parameters/FlashParameters.hpp | 6 +- .../constitutive/unitTests/CMakeLists.txt | 2 + .../unitTests/TestFluidUtilities.hpp | 18 +- .../testNegativeTwoPhaseFlashJacobian.cpp | 259 +++++++++ .../unitTests/testStabilityTest2Comp.cpp | 33 +- .../unitTests/testStabilityTestJacobian.cpp | 241 +++++++++ 13 files changed, 1522 insertions(+), 172 deletions(-) create mode 100644 src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp create mode 100644 src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashJacobian.cpp create mode 100644 src/coreComponents/constitutive/unitTests/testStabilityTestJacobian.cpp diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index dae28e482e0..11f5c5af8c4 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -98,6 +98,7 @@ set( constitutive_headers fluid/multifluid/compositional/functions/SoreideWhitsonEOSPhaseModel_impl.hpp fluid/multifluid/compositional/functions/SoreideWhitsonEOSPhaseModel.hpp fluid/multifluid/compositional/functions/StabilityTest.hpp + fluid/multifluid/compositional/functions/StabilityTest_impl.hpp fluid/multifluid/compositional/functions/Utilities.hpp fluid/multifluid/compositional/models/CompositionalDensity.hpp fluid/multifluid/compositional/models/ConstantViscosity.hpp diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp index 1509701600a..0dc551f3a57 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp @@ -110,6 +110,41 @@ struct NegativeTwoPhaseFlash arraySlice2d< real64, USD3 > const & liquidCompositionDerivs, arraySlice2d< real64, USD3 > const & vapourCompositionDerivs ); + template< int USD1, int USD2, int USD3 > + GEOS_HOST_DEVICE + static real64 calculateResidual( integer const numComps, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + arraySlice1d< real64 const, USD1 > const & kValues, + real64 const & vapourPhaseMoleFraction, + arraySlice1d< real64, USD2 > const & liquidComposition, + arraySlice1d< real64, USD2 > const & vapourComposition, + arraySlice1d< real64 > const & logLiquidFugacity, + arraySlice1d< real64 > const & logVapourFugacity, + arraySlice1d< real64, USD3 > const & residual ); + + template< int USD1, int USD2, int USD3, int USD4 > + GEOS_HOST_DEVICE + static void calculateResidualAndJacobian( integer const numComps, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + arraySlice1d< real64 const, USD1 > const & kValues, + real64 const & vapourPhaseMoleFraction, + arraySlice1d< real64, USD2 > const & liquidComposition, + arraySlice1d< real64, USD2 > const & vapourComposition, + arraySlice1d< real64 > const & logLiquidFugacity, + arraySlice1d< real64 > const & logVapourFugacity, + arraySlice2d< real64 > const & logLiquidFugacityDerivs, + arraySlice2d< real64 > const & logVapourFugacityDerivs, + arraySlice1d< real64, USD3 > const & residual, + arraySlice2d< real64, USD4 > const & jacobian ); + private: /** * @brief Calculate the derivatives of the flash. diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index f251d632117..df99bc20b57 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -261,6 +261,295 @@ void NegativeTwoPhaseFlash::computeDerivatives( } } +template< int USD > +void calculateResidualAndJacobian_gen( int const numComps, + double const pressure, + double const temperature, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + std::vector< double > const & totalComposition, + double const V, + std::vector< double > const & kValues, + std::vector< double > & residual, + std::vector< std::vector< double > > & jacobian ); +template< int USD1, int USD2, int USD3 > +GEOS_HOST_DEVICE +real64 NegativeTwoPhaseFlash::calculateResidual( integer const numComps, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + arraySlice1d< real64 const, USD1 > const & kValues, + real64 const & vapourPhaseMoleFraction, + arraySlice1d< real64, USD2 > const & liquidComposition, + arraySlice1d< real64, USD2 > const & vapourComposition, + arraySlice1d< real64 > const & logLiquidFugacity, + arraySlice1d< real64 > const & logVapourFugacity, + arraySlice1d< real64, USD3 > const & residual ) +{ + // Calculate phase and normalize compositions + real64 massBalance = 0.0; + for( integer ic = 0; ic < numComps; ++ic ) + { + liquidComposition[ic] = composition[ic] / ( 1.0 + vapourPhaseMoleFraction * ( kValues[ic] - 1.0 ) ); + vapourComposition[ic] = kValues[ic] * liquidComposition[ic]; + massBalance += (vapourComposition[ic] - liquidComposition[ic]); + } + + normalizeComposition( numComps, liquidComposition ); + normalizeComposition( numComps, vapourComposition ); + + FugacityCalculator::computeLogFugacity( numComps, + pressure, + temperature, + liquidComposition.toSliceConst(), + componentProperties, + flashData.liquidEos, + flashData, + logLiquidFugacity ); + FugacityCalculator::computeLogFugacity( numComps, + pressure, + temperature, + vapourComposition.toSliceConst(), + componentProperties, + flashData.vapourEos, + flashData, + logVapourFugacity ); + + // Compute fugacity ratios and calculate the error + real64 error = 0.0; + for( integer ic = 0; ic < numComps; ++ic ) + { + residual[ic] = liquidComposition[ic]*LvArray::math::exp( logLiquidFugacity[ic] ) - vapourComposition[ic]*LvArray::math::exp( logVapourFugacity[ic] ); + error += (residual[ic]*residual[ic]); + } + residual[numComps] = massBalance; + error += (residual[numComps]*residual[numComps]); + error = LvArray::math::sqrt( error ); + + return error; +} + +template< int USD1, int USD2, int USD3, int USD4 > +GEOS_HOST_DEVICE +void NegativeTwoPhaseFlash::calculateResidualAndJacobian( integer const numComps, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + arraySlice1d< real64 const, USD1 > const & kValues, + real64 const & vapourPhaseMoleFraction, + arraySlice1d< real64, USD2 > const & liquidComposition, + arraySlice1d< real64, USD2 > const & vapourComposition, + arraySlice1d< real64 > const & logLiquidFugacity, + arraySlice1d< real64 > const & logVapourFugacity, + arraySlice2d< real64 > const & logLiquidFugacityDerivs, + arraySlice2d< real64 > const & logVapourFugacityDerivs, + arraySlice1d< real64, USD3 > const & residual, + arraySlice2d< real64, USD4 > const & jacobian ) +{ + /* + GEOS_UNUSED_VAR( numComps ); + GEOS_UNUSED_VAR( pressure ); + GEOS_UNUSED_VAR( temperature ); + GEOS_UNUSED_VAR( composition ); + GEOS_UNUSED_VAR( componentProperties ); + GEOS_UNUSED_VAR( flashData ); + GEOS_UNUSED_VAR( kValues ); + GEOS_UNUSED_VAR( vapourPhaseMoleFraction ); + GEOS_UNUSED_VAR( liquidComposition ); + GEOS_UNUSED_VAR( vapourComposition ); + GEOS_UNUSED_VAR( logLiquidFugacity ); + GEOS_UNUSED_VAR( logVapourFugacity ); + GEOS_UNUSED_VAR( logLiquidFugacityDerivs ); + GEOS_UNUSED_VAR( logVapourFugacityDerivs ); + GEOS_UNUSED_VAR( residual ); + GEOS_UNUSED_VAR( jacobian ); + + std::vector< double > compositionVector( numComps ); + std::vector< double > kValuesVector( numComps ); + std::vector< double > residualVector( numComps+1, 0.0 ); + std::vector< std::vector< double > > jacobianVector( numComps+1, residualVector ); + for( integer ic = 0; ic < numComps; ++ic ) + { + compositionVector[ic] = composition[ic]; + kValuesVector[ic] = kValues[ic]; + } + + calculateResidualAndJacobian_gen< 0 >( numComps, + pressure, + temperature, + componentProperties, + flashData, + compositionVector, + vapourPhaseMoleFraction, + kValuesVector, + residualVector, + jacobianVector ); + for( integer ic = 0; ic <= numComps; ++ic ) + { + residual[ic] = residualVector[ic]; + for( integer jc = 0; jc <= numComps; ++jc ) + { + jacobian( ic, jc ) = jacobianVector[ic][jc]; + } + } + + for( integer ic = 0; ic <= numComps; ++ic ) + { + residual[ic] = 0.0; + // for( integer jc = 0; jc <= numComps; ++jc ) + // { + // jacobian( ic, jc ) = 0.0; + // } + } + */ + real64 const & V = vapourPhaseMoleFraction; + + // Calculate phase compositions --- + for( integer ic = 0; ic < numComps; ++ic ) + { + real64 const denominator = 1.0 + V * (kValues[ic] - 1.0); + liquidComposition[ic] = composition[ic] / denominator; + vapourComposition[ic] = kValues[ic] * liquidComposition[ic]; + } + + real64 const sumX = normalizeComposition( numComps, liquidComposition ); + real64 const sumY = normalizeComposition( numComps, vapourComposition ); + + // Calculate the fugacity and derivatives + FugacityCalculator::computeLogFugacityDerivatives( numComps, + pressure, + temperature, + liquidComposition.toSliceConst(), + componentProperties, + flashData.liquidEos, + flashData, + logLiquidFugacity, + logLiquidFugacityDerivs ); + FugacityCalculator::computeLogFugacityDerivatives( numComps, + pressure, + temperature, + vapourComposition.toSliceConst(), + componentProperties, + flashData.vapourEos, + flashData, + logVapourFugacity, + logVapourFugacityDerivs ); + + // Convert from log (use same memory space: log fugacity no longer required) + arraySlice1d< real64 > const & liquidFugacity = logLiquidFugacity; + arraySlice1d< real64 > const & vapourFugacity = logVapourFugacity; + for( integer ic = 0; ic < numComps; ++ic ) + { + liquidFugacity[ic] = LvArray::math::exp( logLiquidFugacity[ic] ); + vapourFugacity[ic] = LvArray::math::exp( logVapourFugacity[ic] ); + } + + // Calculate the residual vector + residual[numComps] = 0.0; + for( integer ic = 0; ic < numComps; ++ic ) + { + real64 const zi = composition[ic]; + real64 const xi = liquidComposition[ic]; + real64 const yi = vapourComposition[ic]; + real64 const Ki = kValues[ic]; + residual[ic] = xi * liquidFugacity[ic] - yi * vapourFugacity[ic]; + residual[numComps] += zi * (Ki - 1.0) / (1.0 + V * (Ki - 1.0)); + } + + real64 const invSumX = 1.0/sumX; + real64 const invSumY = 1.0/sumY; + + real64 sum_d_xs_d_V = 0.0; + real64 sum_d_ys_d_V = 0.0; + for( int ic = 0; ic < numComps; ++ic ) + { + real64 const zi = composition[ic]; + real64 const Ki = kValues[ic]; + + real64 const invKi = 1.0 / ( 1.0 + V * (Ki - 1.0) ); + real64 const d_xsi_d_V = -zi * (Ki - 1.0) * invKi * invKi; + real64 const d_ysi_d_V = Ki * d_xsi_d_V; + + sum_d_xs_d_V += d_xsi_d_V; + sum_d_ys_d_V += d_ysi_d_V; + } + + // Start calculating the Jacobian + real64 sum_j_N_V = 0.0; + for( integer ic = 0; ic < numComps; ++ic ) + { + real64 const zi = composition[ic]; + real64 const xi = liquidComposition[ic]; + real64 const yi = vapourComposition[ic]; + real64 const Ki = kValues[ic]; + + real64 const invKi = 1.0 / ( 1.0 + V * (Ki - 1.0) ); + real64 const d_xsi_d_V = -zi * (Ki - 1.0) * invKi * invKi; + real64 const d_ysi_d_V = Ki * d_xsi_d_V; + + real64 const d_xi_d_V = (d_xsi_d_V - xi * sum_d_xs_d_V) * invSumX; + real64 const d_yi_d_V = (d_ysi_d_V - yi * sum_d_ys_d_V) * invSumY; + + real64 sum_dXid_xj_dxj_d_V = 0.0; + real64 sum_dYid_yj_dyj_d_V = 0.0; + + for( integer jc = 0; jc < numComps; ++jc ) + { + real64 const zj = composition[jc]; + real64 const xj = liquidComposition[jc]; + real64 const yj = vapourComposition[jc]; + real64 const Kj = kValues[jc]; + + real64 const dphiLi_dxj = logLiquidFugacityDerivs( ic, Deriv::dC + jc ); + real64 const dphiVi_dyj = logVapourFugacityDerivs( ic, Deriv::dC + jc ); + + real64 const invKj = 1.0 / ( 1.0 + V * (Kj - 1.0) ); + real64 const d_xsj_d_V = -zj * (Kj - 1.0) * invKj * invKj; + real64 const d_ysj_d_V = Kj * d_xsj_d_V; + + real64 const d_xsj_d_kj = -zj * V * Kj * invKj * invKj; + real64 const d_ysj_d_kj = Kj * (xj * sumX + d_xsj_d_kj); + + real64 const d_xj_d_V = (d_xsj_d_V - xj * sum_d_xs_d_V) * invSumX; + real64 const d_yj_d_V = (d_ysj_d_V - yj * sum_d_ys_d_V) * invSumY; + + sum_dXid_xj_dxj_d_V += dphiLi_dxj * d_xj_d_V; + sum_dYid_yj_dyj_d_V += dphiVi_dyj * d_yj_d_V; + + real64 const dij = (ic == jc) ? 1.0 : 0.0; + real64 const d_xi_d_kj = d_xsj_d_kj * (dij - xi) * invSumX; + real64 const d_yi_d_kj = d_ysj_d_kj * (dij - yi) * invSumY; + + real64 sum_dXid_xk_dxk_d_kj = 0.0; + real64 sum_dYid_yk_dyk_d_kj = 0.0; + for( integer kc = 0; kc < numComps; ++kc ) + { + real64 const djk = (jc == kc) ? 1.0 : 0.0; + real64 const d_xk_d_kj = d_xsj_d_kj * (djk - liquidComposition[kc]) * invSumX; + real64 const d_yk_d_kj = d_ysj_d_kj * (djk - vapourComposition[kc]) * invSumY; + + real64 const dphiLi_dxk = logLiquidFugacityDerivs( ic, Deriv::dC + kc ); + real64 const dphiVi_dyk = logVapourFugacityDerivs( ic, Deriv::dC + kc ); + + sum_dXid_xk_dxk_d_kj += dphiLi_dxk * d_xk_d_kj; + sum_dYid_yk_dyk_d_kj += dphiVi_dyk * d_yk_d_kj; + } + jacobian( ic, jc ) = liquidFugacity[ic] * (d_xi_d_kj + xi * sum_dXid_xk_dxk_d_kj) - + vapourFugacity[ic] * (d_yi_d_kj + yi * sum_dYid_yk_dyk_d_kj); + } + jacobian( ic, numComps ) = liquidFugacity[ic] * (d_xi_d_V + xi * sum_dXid_xj_dxj_d_V) - + vapourFugacity[ic] * (d_yi_d_V + yi * sum_dYid_yj_dyj_d_V); + jacobian( numComps, ic ) = zi * Ki * invKi* invKi; + + sum_j_N_V -= zi * (Ki - 1.0) * (Ki - 1.0) * invKi * invKi; + } + jacobian( numComps, numComps ) = sum_j_N_V; +} + template< integer USD1, integer USD2, integer USD3 > GEOS_HOST_DEVICE void NegativeTwoPhaseFlash::computeDerivatives( @@ -410,6 +699,223 @@ bool NegativeTwoPhaseFlash::truncateCompositions( integer const numComps, return (V < MultiFluidConstants::epsilon|| L < MultiFluidConstants::epsilon); } +// Assume calculateFugacity is defined elsewhere. +// This function calculates the log fugacities and their derivatives for a given phase. +template< int USD > +void calculateFugacity( int const numComps, + double const pressure, + double const temperature, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + EquationOfStateType const equationOfState, + std::vector< double > const & phaseComposition, + std::vector< double > & logFugacity, + std::vector< std::vector< double > > & logFugacityDerivatives ) +{ + StackArray< real64, 2, 2*9 > workSpace( 2, numComps ); + arraySlice1d< real64, USD > phaseCompositionSlice = workSpace[0]; + arraySlice1d< real64, USD > logFugacitySlice = workSpace[1]; + StackArray< real64, 2, 9*11 > derivatives( numComps, numComps+2 ); + for( integer ic = 0; ic < numComps; ++ic ) + { + phaseCompositionSlice[ic] = phaseComposition[ic]; + } + FugacityCalculator::computeLogFugacityDerivatives( numComps, + pressure, + temperature, + phaseCompositionSlice.toSliceConst(), + componentProperties, + equationOfState, + flashData, + logFugacitySlice, + derivatives.toSlice() ); + for( integer ic = 0; ic < numComps; ++ic ) + { + logFugacity[ic] = logFugacitySlice[ic]; + for( integer jc = 0; jc < numComps; ++jc ) + { + logFugacityDerivatives[ic][jc] = derivatives( ic, 2 + jc ); + } + } +} + +/** + * @brief Calculates the residual vector and Jacobian matrix for a flash calculation. + * * @param numComps Number of components (N). + * @param pressure System pressure. + * @param temperature System temperature. + * @param totalComposition The total mole fractions (z_i). + * @param V The vapor fraction guess. + * @param kValues The K-values (K_i). + * @param residual Output vector for the residual F. + * @param jacobian Output matrix for the Jacobian of F. + */ +template< int USD > +void calculateResidualAndJacobian_gen( int const numComps, + double const pressure, + double const temperature, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + std::vector< double > const & totalComposition, + double const V, + std::vector< double > const & kValues, + std::vector< double > & residual, + std::vector< std::vector< double > > & jacobian ) +{ + + // Helper lambda for Kronecker delta + auto kronecker_delta = []( int i, int j ) { return (i == j) ? 1.0 : 0.0; }; + + // --- Part 1: Calculate intermediate values and phase compositions --- + std::vector< double > x_s( numComps ); + std::vector< double > y_s( numComps ); + double x_sum = 0.0; + double y_sum = 0.0; + + for( int i = 0; i < numComps; ++i ) + { + double denominator = 1.0 + V * (kValues[i] - 1.0); + x_s[i] = totalComposition[i] / denominator; + y_s[i] = kValues[i] * x_s[i]; + x_sum += x_s[i]; + y_sum += y_s[i]; + } + + std::vector< double > x_i( numComps ); + std::vector< double > y_i( numComps ); + for( int i = 0; i < numComps; ++i ) + { + x_i[i] = x_s[i] / x_sum; + y_i[i] = y_s[i] / y_sum; + } + + // --- Part 2: Calculate log fugacities and their derivatives --- + std::vector< double > X_i( numComps ); + std::vector< std::vector< double > > dXid_xj( numComps, std::vector< double >( numComps )); + calculateFugacity< USD >( numComps, + pressure, + temperature, + componentProperties, + flashData, + flashData.liquidEos, + x_i, + X_i, + dXid_xj ); + + std::vector< double > Y_i( numComps ); + std::vector< std::vector< double > > dYid_yj( numComps, std::vector< double >( numComps )); + calculateFugacity< USD >( numComps, + pressure, + temperature, + componentProperties, + flashData, + flashData.vapourEos, + y_i, + Y_i, + dYid_yj ); + + // --- Part 3: Calculate the residual vector --- + residual.resize( numComps + 1 ); + for( int i = 0; i < numComps; ++i ) + { + residual[i] = x_i[i] * std::exp( X_i[i] ) - y_i[i] * std::exp( Y_i[i] ); + } + + double fV_sum = 0.0; + for( int i = 0; i < numComps; ++i ) + { + fV_sum += totalComposition[i] * (kValues[i] - 1.0) / (1.0 + V * (kValues[i] - 1.0)); + } + residual[numComps] = fV_sum; + + + // --- Part 4: Calculate the Jacobian matrix --- + jacobian.assign( numComps + 1, std::vector< double >( numComps + 1, 0.0 )); + + // Pre-calculate intermediate derivatives to avoid redundant calculations + std::vector< double > d_xs_d_V( numComps ); + std::vector< double > d_ys_d_V( numComps ); + double sum_d_xs_d_V = 0.0; + double sum_d_ys_d_V = 0.0; + for( int i = 0; i < numComps; ++i ) + { + double denominator = 1.0 + V * (kValues[i] - 1.0); + d_xs_d_V[i] = -totalComposition[i] * (kValues[i] - 1.0) / (denominator * denominator); + d_ys_d_V[i] = kValues[i] * d_xs_d_V[i]; + sum_d_xs_d_V += d_xs_d_V[i]; + sum_d_ys_d_V += d_ys_d_V[i]; + } + + std::vector< double > d_xsj_d_kj( numComps ); + std::vector< double > d_ysj_d_kj( numComps ); + for( int j = 0; j < numComps; ++j ) + { + double denominator = 1.0 + V * (kValues[j] - 1.0); + d_xsj_d_kj[j] = -totalComposition[j] * V * kValues[j] / (denominator * denominator); + d_ysj_d_kj[j] = kValues[j] * x_s[j] + kValues[j] * d_xsj_d_kj[j]; + } + + // Fill the top-left block J_ij (i=1..N, j=1..N) + for( int i = 0; i < numComps; ++i ) + { + for( int j = 0; j < numComps; ++j ) + { + double d_xi_d_kj = d_xsj_d_kj[j] * (kronecker_delta( i, j ) / x_sum - x_s[i] / (x_sum * x_sum)); + double d_yi_d_kj = d_ysj_d_kj[j] * (kronecker_delta( i, j ) / y_sum - y_s[i] / (y_sum * y_sum)); + + double sum_dXid_xk_dxk_d_kj = 0.0; + double sum_dYid_yk_dyk_d_kj = 0.0; + for( int k = 0; k < numComps; ++k ) + { + double d_xk_d_kj = d_xsj_d_kj[j] * (kronecker_delta( k, j ) / x_sum - x_s[k] / (x_sum * x_sum)); + double d_yk_d_kj = d_ysj_d_kj[j] * (kronecker_delta( k, j ) / y_sum - y_s[k] / (y_sum * y_sum)); + sum_dXid_xk_dxk_d_kj += dXid_xj[i][k] * d_xk_d_kj; + sum_dYid_yk_dyk_d_kj += dYid_yj[i][k] * d_yk_d_kj; + } + + jacobian[i][j] = std::exp( X_i[i] ) * d_xi_d_kj + x_i[i] * std::exp( X_i[i] ) * sum_dXid_xk_dxk_d_kj - + std::exp( Y_i[i] ) * d_yi_d_kj - y_i[i] * std::exp( Y_i[i] ) * sum_dYid_yk_dyk_d_kj; + } + } + + // Fill the top-right block J_i,N+1 (i=1..N) + for( int i = 0; i < numComps; ++i ) + { + double d_xi_d_V = (d_xs_d_V[i] * x_sum - x_s[i] * sum_d_xs_d_V) / (x_sum * x_sum); + double d_yi_d_V = (d_ys_d_V[i] * y_sum - y_s[i] * sum_d_ys_d_V) / (y_sum * y_sum); + + double sum_dXid_xk_dxk_d_V = 0.0; + double sum_dYid_yk_dyk_d_V = 0.0; + for( int k = 0; k < numComps; ++k ) + { + double d_xk_d_V = (d_xs_d_V[k] * x_sum - x_s[k] * sum_d_xs_d_V) / (x_sum * x_sum); + double d_yk_d_V = (d_ys_d_V[k] * y_sum - y_s[k] * sum_d_ys_d_V) / (y_sum * y_sum); + sum_dXid_xk_dxk_d_V += dXid_xj[i][k] * d_xk_d_V; + sum_dYid_yk_dyk_d_V += dYid_yj[i][k] * d_yk_d_V; + } + + jacobian[i][numComps] = std::exp( X_i[i] ) * d_xi_d_V + x_i[i] * std::exp( X_i[i] ) * sum_dXid_xk_dxk_d_V - + std::exp( Y_i[i] ) * d_yi_d_V - y_i[i] * std::exp( Y_i[i] ) * sum_dYid_yk_dyk_d_V; + } + + // Fill the bottom-left block J_N+1,j (j=1..N) + for( int j = 0; j < numComps; ++j ) + { + double denominator = 1.0 + V * (kValues[j] - 1.0); + jacobian[numComps][j] = totalComposition[j] * kValues[j] / (denominator * denominator); + } + + // Fill the bottom-right entry J_N+1,N+1 + double sum_j_N_V = 0.0; + for( int i = 0; i < numComps; ++i ) + { + double denominator = 1.0 + V * (kValues[i] - 1.0); + sum_j_N_V += -totalComposition[i] * std::pow( kValues[i] - 1.0, 2 ) / (denominator * denominator); + } + jacobian[numComps][numComps] = sum_j_N_V; +} + + } // namespace compositional } // namespace constitutive } // namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp index 3e017c005ea..051353fbb82 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp @@ -75,159 +75,7 @@ struct StabilityTest arraySlice1d< integer const > const & discreteFlashParameters, bool & unstableMixture, EquationOfStateType & incipientEquationOfState, - arraySlice1d< real64 > const & incipientComposition ) - { - stackArray2d< real64, 4*maxNumComps > workSpace( 4, numComps ); - arraySlice1d< real64 > logFugacity = workSpace[0]; - arraySlice1d< real64 > normalizedComposition = workSpace[1]; - arraySlice1d< real64 > logTrialComposition = workSpace[2]; - arraySlice1d< real64 > hyperplane = workSpace[3]; // h-parameter - stackArray1d< integer, maxNumComps > availableComponents( numComps ); - - //integer const presentCount = - calculatePresentComponents( numComps, composition, availableComponents ); - auto const presentComponents = availableComponents.toSliceConst(); - - LvArray::forValuesInSlice( workSpace.toSlice(), setZero ); - - // Extract flash parameters - integer const maxIterations = discreteFlashParameters[FlashParameters::STABILITY_MAX_ITERATIONS]; - real64 const stabilityThreshold = continuousFlashParameters[FlashParameters::STABILITY_THRESHOLD]; - real64 const stabilityTolerance = continuousFlashParameters[FlashParameters::STABILITY_TOLERANCE]; - - integer const numConfigSteps = flashData.liquidEos == flashData.vapourEos ? 1 : 2; - - // Initialise by assuming a stable mixture - unstableMixture = false; - - // Flag to indicate all trial compositions converged - bool allConverged = true; - - // Measure of distance to trivial solution - real64 maxDistanceToTrivialSolution = 0.0; - - for( integer configStep = 0; configStep < numConfigSteps; ++configStep ) - { - EquationOfStateType const sampleEos = (configStep == 0) ? flashData.liquidEos : flashData.vapourEos; - EquationOfStateType const incipientEos = (configStep == 0) ? flashData.vapourEos : flashData.liquidEos; - - // Calculate the hyperplane parameter - // h_i = log( z_i ) + log( phi_i ) - FugacityCalculator::computeLogFugacity( numComps, - pressure, - temperature, - composition, - componentProperties, - sampleEos, - flashData, - logFugacity ); - for( integer const ic : presentComponents ) - { - hyperplane[ic] = LvArray::math::log( composition[ic] ) + logFugacity[ic]; - } - - for( real64 const alpha : { 1.0, -1.0, 0.0 } ) - { - // Initialise next sample - if( LvArray::math::abs( alpha ) < MultiFluidConstants::epsilon ) - { - for( integer const ic : presentComponents ) - { - logTrialComposition[ic] = 0.0; - normalizedComposition[ic] = 1.0; - } - } - else - { - for( integer const ic : presentComponents ) - { - logTrialComposition[ic] = LvArray::math::log( composition[ic] ) + alpha*LvArray::math::log( kValues[ic] ); - normalizedComposition[ic] = LvArray::math::exp( logTrialComposition[ic] ); - } - } - - // Start iterations for this sample - bool converged = false; - - for( localIndex iterationCount = 0; iterationCount < maxIterations; ++iterationCount ) - { - // Normalise the composition and calculate the fugacity - normalizeComposition( numComps, normalizedComposition ); - FugacityCalculator::computeLogFugacity( numComps, - pressure, - temperature, - normalizedComposition.toSliceConst(), - componentProperties, - incipientEos, - flashData, - logFugacity ); - - // Calculate the stationarity condition - real64 error = 0.0; - for( integer const ic : presentComponents ) - { - real64 const dG = logTrialComposition[ic] + logFugacity[ic] - hyperplane[ic]; - error += (dG*dG); - } - error = LvArray::math::sqrt( error ); - - // Check stationarity - if( error < stabilityTolerance ) - { - converged = true; - break; - } - - // Update to next step - for( integer const ic : presentComponents ) - { - logTrialComposition[ic] = hyperplane[ic] - logFugacity[ic]; - normalizedComposition[ic] = LvArray::math::exp( logTrialComposition[ic] ); - } - } - allConverged = allConverged && converged; - - // Calculate the tangent-plane-distance (TPD) and distance to the trivial solution - real64 tpd = 1.0; - real64 distance = 0.0; - for( integer const ic : presentComponents ) - { - real64 const dZ = normalizedComposition[ic] - composition[ic]; - real64 const dG = logTrialComposition[ic] + logFugacity[ic] - hyperplane[ic]; - tpd += normalizedComposition[ic] * (dG - 1.0); - distance += (dZ*dZ); - } - - if( maxDistanceToTrivialSolution < distance ) - { - maxDistanceToTrivialSolution = distance; - incipientEquationOfState = incipientEos; - for( integer ic = 0; ic < numComps; ++ic ) - { - incipientComposition[ic] = normalizedComposition[ic]; - } - } - // The mixture is unstable if either the TPD is negative or if the TPD is zero but the incipient composition - // is different from the sample composition - // stabilityThreshold is negative (default -1e-8) - if( tpd < stabilityThreshold ) - { - unstableMixture = true; - } - else if((tpd < -stabilityThreshold) && (-stabilityThreshold < distance)) - { - unstableMixture = true; - } - if( unstableMixture ) - { - return true; - } - } - } - - // The test is successful if either we have an unstable mixture or all test compositions converged to stationarity - return unstableMixture || allConverged; - } + arraySlice1d< real64 > const & incipientComposition ); /** * @brief Compute derivatives of the incipient phase composition @@ -335,6 +183,38 @@ struct StabilityTest } } } + + template< int USD1, int USD2, int USD3 > + GEOS_HOST_DEVICE + static real64 calculateResidual( integer const numComps, + arraySlice1d< integer const > const & presentComponents, + real64 const pressure, + real64 const temperature, + ComponentProperties::KernelWrapper const & componentProperties, + EquationOfStateType const equationOfState, + FlashData const & flashData, + arraySlice1d< real64 const, USD1 > const & logTestComposition, + real64 & tangentPlaneDistance, + arraySlice1d< real64, USD2 > const & testComposition, + arraySlice1d< real64 > const & testLogFugacity, + arraySlice1d< real64, USD3 > const & residual ); + + template< int USD1, int USD2, int USD3, int USD4 > + GEOS_HOST_DEVICE + static real64 calculateResidualAndJacobian( integer const numComps, + arraySlice1d< integer const > const & presentComponents, + real64 const pressure, + real64 const temperature, + ComponentProperties::KernelWrapper const & componentProperties, + EquationOfStateType const equationOfState, + FlashData const & flashData, + arraySlice1d< real64 const, USD1 > const & logTestComposition, + real64 & tangentPlaneDistance, + arraySlice1d< real64, USD2 > const & testComposition, + arraySlice1d< real64 > const & testFugacity, + arraySlice2d< real64 > const & logTestFugacityDerivs, + arraySlice1d< real64, USD3 > const & residual, + arraySlice2d< real64, USD4 > const & jacobian ); }; } // namespace compositional @@ -343,4 +223,7 @@ struct StabilityTest } // namespace geos +// Include the implementation +#include "StabilityTest_impl.hpp" + #endif //GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_STABILITYTEST_HPP_ diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp new file mode 100644 index 00000000000..146576b7e04 --- /dev/null +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp @@ -0,0 +1,373 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file StabilityTest_impl.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_STABILITYTEST_IMPL_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_STABILITYTEST_IMPL_HPP_ + +#include "StabilityTest.hpp" + +namespace geos +{ + +namespace constitutive +{ + +namespace compositional +{ + +template< integer USD1, integer USD2 > +GEOS_HOST_DEVICE +bool StabilityTest::compute( integer const numComps, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, USD1 > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + arraySlice1d< real64 const, USD2 > const & kValues, + arraySlice1d< real64 const > const & continuousFlashParameters, + arraySlice1d< integer const > const & discreteFlashParameters, + bool & unstableMixture, + EquationOfStateType & incipientEquationOfState, + arraySlice1d< real64 > const & incipientComposition ) +{ + integer constexpr maxDofs = maxNumComps + 2; + + integer const numDofs = 2 + numComps; + + stackArray2d< real64, 5*maxNumComps > workSpace( 5, numComps ); + stackArray2d< real64, maxNumComps *maxNumComps > jacobian( numComps, numComps ); + stackArray2d< real64, maxNumComps *maxDofs > derivatives( numComps, numDofs ); + arraySlice1d< real64 > logFugacity = workSpace[0]; + arraySlice1d< real64 > logTestComposition = workSpace[1]; + arraySlice1d< real64 > testComposition = workSpace[2]; + arraySlice1d< real64 > residual = workSpace[3]; + arraySlice1d< real64 > hyperplane = workSpace[4]; // h-parameter + stackArray1d< integer, maxNumComps > availableComponents( numComps ); + + calculatePresentComponents( numComps, composition, availableComponents ); + auto const presentComponents = availableComponents.toSliceConst(); + + LvArray::forValuesInSlice( workSpace.toSlice(), setZero ); + + // Extract flash parameters + integer const maxIterations = discreteFlashParameters[FlashParameters::STABILITY_MAX_ITERATIONS]; + real64 const stabilityThreshold = continuousFlashParameters[FlashParameters::STABILITY_THRESHOLD]; + real64 const stabilityTolerance = continuousFlashParameters[FlashParameters::STABILITY_TOLERANCE]; + real64 const stabilitySSITolerance = LvArray::math::max( stabilityTolerance, continuousFlashParameters[FlashParameters::SSI_TOLERANCE] ); + + integer const numConfigSteps = flashData.liquidEos == flashData.vapourEos ? 1 : 2; + + // Initialise by assuming a stable mixture + unstableMixture = false; + + // Flag to indicate all trial compositions converged + bool allConverged = true; + + // Measure of distance to trivial solution + real64 maxDistanceToTrivialSolution = 0.0; + + for( integer configStep = 0; configStep < numConfigSteps; ++configStep ) + { + EquationOfStateType const sampleEos = (configStep == 0) ? flashData.liquidEos : flashData.vapourEos; + EquationOfStateType const incipientEos = (configStep == 0) ? flashData.vapourEos : flashData.liquidEos; + + real64 tpd = 0.0; + + // Calculate the hyperplane parameter + // h_i = log( z_i ) + log( phi_i ) + LvArray::forValuesInSlice( hyperplane, setZero ); + for( integer const ic : presentComponents ) + { + logTestComposition[ic] = LvArray::math::log( composition[ic] ); + } + calculateResidual( numComps, + presentComponents, + pressure, + temperature, + componentProperties, + sampleEos, + flashData, + logTestComposition.toSliceConst(), + tpd, + testComposition, + logFugacity, + hyperplane ); + + for( real64 const alpha : { 1.0, -1.0, 0.0 } ) + { + if( LvArray::math::abs( alpha ) < MultiFluidConstants::epsilon ) + { + for( integer const ic : presentComponents ) + { + logTestComposition[ic] = 1.0; + } + } + else + { + for( integer const ic : presentComponents ) + { + real64 const logK = LvArray::math::log( kValues[ic] ); + logTestComposition[ic] = LvArray::math::log( composition[ic] ) + alpha * logK; + } + } + + // Start iterations for this sample + bool converged = false; + + localIndex iterationCount = 0; + + // Start with SSI iterations + for(; iterationCount < maxIterations; ++iterationCount ) + { + for( integer const ic : presentComponents ) + { + residual[ic] = -hyperplane[ic]; + } + real64 error = calculateResidual( numComps, + presentComponents, + pressure, + temperature, + componentProperties, + incipientEos, + flashData, + logTestComposition.toSliceConst(), + tpd, + testComposition, + logFugacity, + residual ); + // Update to next step + for( integer const ic : presentComponents ) + { + logTestComposition[ic] -= residual[ic]; + } + std::cout << configStep << " " + << std::fixed << std::setprecision( 0 ) << std::setw( 3 ) << alpha << " " + << std::setw( 3 ) << iterationCount << " " + << std::scientific << std::setprecision( 6 ) << std::setw( 13 ) << tpd << " " + << std::scientific << std::setprecision( 6 ) << std::setw( 13 ) << error << " " + << std::fixed << std::setprecision( 6 ) << testComposition << " " + << "\n"; + + // Check stationarity + if( error < stabilitySSITolerance ) + { + converged = true; + break; + } + } + std::cout << "----------\n"; + + // Start with Newton iterations + for(; iterationCount < maxIterations; ++iterationCount ) + { + for( integer const ic : presentComponents ) + { + residual[ic] = -hyperplane[ic]; + } + real64 error = calculateResidualAndJacobian( numComps, + presentComponents, + pressure, + temperature, + componentProperties, + incipientEos, + flashData, + logTestComposition.toSliceConst(), + tpd, + testComposition, + logFugacity, + derivatives.toSlice(), + residual, + jacobian.toSlice() ); + solveLinearSystem( jacobian.toSlice(), residual ); + // Update to next step + for( integer const ic : presentComponents ) + { + logTestComposition[ic] -= residual[ic]; + } + + std::cout << configStep << " " + << std::fixed << std::setprecision( 0 ) << std::setw( 3 ) << alpha << " " + << std::setw( 3 ) << iterationCount << " " + << std::scientific << std::setprecision( 6 ) << std::setw( 13 ) << tpd << " " + << std::scientific << std::setprecision( 6 ) << std::setw( 13 ) << error << " " + << std::fixed << std::setprecision( 6 ) << testComposition << " " + << "\n"; + // Check stationarity + if( error < stabilityTolerance ) + { + converged = true; + break; + } + } + std::cout << "-----------------------------------------------------------------\n"; + allConverged = allConverged && converged; + + // Calculate the tangent-plane-distance (TPD) and distance to the trivial solution + real64 distance = 0.0; + for( integer const ic : presentComponents ) + { + real64 const dZ = testComposition[ic] - composition[ic]; + distance += (dZ*dZ); + } + + if( maxDistanceToTrivialSolution < distance ) + { + maxDistanceToTrivialSolution = distance; + incipientEquationOfState = incipientEos; + for( integer ic = 0; ic < numComps; ++ic ) + { + incipientComposition[ic] = testComposition[ic]; + } + } + // The mixture is unstable if either the TPD is negative or if the TPD is zero but the incipient composition + // is different from the sample composition + // stabilityThreshold is negative (default -1e-8) + if( tpd < stabilityThreshold ) + { + unstableMixture = true; + } + else if((tpd < -stabilityThreshold) && (-stabilityThreshold < distance)) + { + unstableMixture = true; + } + if( unstableMixture ) + { + return true; + } + } + } + + // The test is successful if either we have an unstable mixture or all test compositions converged to stationarity + return unstableMixture || allConverged; +} + +template< int USD1, int USD2, int USD3 > +GEOS_HOST_DEVICE +real64 StabilityTest::calculateResidual( integer const numComps, + arraySlice1d< integer const > const & presentComponents, + real64 const pressure, + real64 const temperature, + ComponentProperties::KernelWrapper const & componentProperties, + EquationOfStateType const equationOfState, + FlashData const & flashData, + arraySlice1d< real64 const, USD1 > const & logTestComposition, + real64 & tangentPlaneDistance, + arraySlice1d< real64, USD2 > const & testComposition, + arraySlice1d< real64 > const & testLogFugacity, + arraySlice1d< real64, USD3 > const & residual ) +{ + for( integer const ic : presentComponents ) + { + testComposition[ic] = LvArray::math::exp( logTestComposition[ic] ); + } + real64 const sumY = normalizeComposition( numComps, testComposition ); + + FugacityCalculator::computeLogFugacity( numComps, + pressure, + temperature, + testComposition.toSliceConst(), + componentProperties, + equationOfState, + flashData, + testLogFugacity ); + + real64 error = 0.0; + tangentPlaneDistance = 1.0; + for( integer const ic : presentComponents ) + { + residual[ic] += logTestComposition[ic] + testLogFugacity[ic]; + tangentPlaneDistance += sumY * testComposition[ic] * (residual[ic] - 1.0); + error += (residual[ic]*residual[ic]); + } + error = LvArray::math::sqrt( error ); + return error; +} + +template< int USD1, int USD2, int USD3, int USD4 > +GEOS_HOST_DEVICE +real64 StabilityTest::calculateResidualAndJacobian( integer const numComps, + arraySlice1d< integer const > const & presentComponents, + real64 const pressure, + real64 const temperature, + ComponentProperties::KernelWrapper const & componentProperties, + EquationOfStateType const equationOfState, + FlashData const & flashData, + arraySlice1d< real64 const, USD1 > const & logTestComposition, + real64 & tangentPlaneDistance, + arraySlice1d< real64, USD2 > const & testComposition, + arraySlice1d< real64 > const & testLogFugacity, + arraySlice2d< real64 > const & logTestFugacityDerivs, + arraySlice1d< real64, USD3 > const & residual, + arraySlice2d< real64, USD4 > const & jacobian ) +{ + for( integer const ic : presentComponents ) + { + testComposition[ic] = LvArray::math::exp( logTestComposition[ic] ); + } + real64 const sumY = normalizeComposition( numComps, testComposition ); + + FugacityCalculator::computeLogFugacityDerivatives( numComps, + pressure, + temperature, + testComposition.toSliceConst(), + componentProperties, + equationOfState, + flashData, + testLogFugacity, + logTestFugacityDerivs ); + + LvArray::forValuesInSlice( jacobian, setZero ); + + tangentPlaneDistance = 1.0; + real64 error = 0.0; + for( integer const ic : presentComponents ) + { + for( integer const jc : presentComponents ) + { + real64 const yj = testComposition[jc]; + + real64 const dphi_ic_dyjc = logTestFugacityDerivs( ic, Deriv::dC + jc ); + + real64 sum_dphi_ic_dykc = dphi_ic_dyjc; + + for( integer const kc : presentComponents ) + { + real64 const yk = testComposition[kc]; + real64 const dphi_ic_dykc = logTestFugacityDerivs( ic, Deriv::dC + kc ); + sum_dphi_ic_dykc -= (dphi_ic_dykc * yk); + } + jacobian( ic, jc ) = yj * sum_dphi_ic_dykc; + } + jacobian( ic, ic ) += 1.0; + + residual[ic] += logTestComposition[ic] + testLogFugacity[ic]; + tangentPlaneDistance += sumY * testComposition[ic] * (residual[ic] - 1.0); + error += (residual[ic]*residual[ic]); + } + error = LvArray::math::sqrt( error ); + return error; +} + +} // namespace compositional + +} // namespace constitutive + +} // namespace geos + +#endif //GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_COMPOSITIONAL_FUNCTIONS_STABILITYTEST_IMPL_HPP_ diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp index d5c5992e9f8..52a7aaab14d 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp @@ -133,6 +133,27 @@ static bool solveLinearSystem( arraySlice2d< real64, USD > const & A, #endif } +/** + * @brief Solve the lineat system for the derivatives of the flash + * @param[in/out] A the coefficient matrix. Destroyed after call + * @param[in/out] X the rhs and solution + * @return @c true if the problem is well solved @c false otherwise + */ +template< int USD1, int USD2 > +GEOS_HOST_DEVICE +static bool solveLinearSystem( arraySlice2d< real64, USD1 > const & A, + arraySlice1d< real64, USD2 > const & x ) +{ +#if defined(GEOS_DEVICE_COMPILE) + GEOS_UNUSED_VAR( A ); + GEOS_UNUSED_VAR( x ); + return false; +#else + BlasLapackLA::solveLinearSystem( A, x ); + return true; +#endif +} + } // namespace compositional } // namespace constitutive } // namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp index 941f28a950b..64a0d0ce7f3 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp @@ -40,6 +40,7 @@ FlashParameters::FlashParameters( std::unique_ptr< ModelParameters > parameters m_continuousParameters[STABILITY_TOLERANCE] = 1.0e-8; m_continuousParameters[FLASH_TOLERANCE] = 1.0e-8; m_continuousParameters[NEGATIVE_FLASH_TOLERANCE] = -1.0e-1; + m_continuousParameters[SSI_TOLERANCE] = 1.0e-3; m_discreteParameters[STABILITY_MAX_ITERATIONS] = 300; m_discreteParameters[FLASH_MAX_ITERATIONS] = 300; @@ -81,6 +82,11 @@ void FlashParameters::registerParametersImpl( MultiFluidBase * fluid ) setInputFlag( dataRepository::InputFlags::OPTIONAL ). setDefaultValue( m_continuousParameters[FLASH_TOLERANCE] ). setDescription( "The tolerance to use to determine convergece of the flash" ); + + fluid->registerWrapper( viewKeyStruct::ssiToleranceString(), &m_continuousParameters[SSI_TOLERANCE] ). + setInputFlag( dataRepository::InputFlags::OPTIONAL ). + setDefaultValue( m_continuousParameters[SSI_TOLERANCE] ). + setDescription( "The tolerance to use to switch from SSI iterations to Newton iterations" ); } void FlashParameters::postInputInitializationImpl( MultiFluidBase const * fluid, @@ -119,6 +125,10 @@ void FlashParameters::postInputInitializationImpl( MultiFluidBase const * fluid, real64 const flashTolerance = m_continuousParameters[FLASH_TOLERANCE]; checkLowerBound( flashTolerance, epsilon, viewKeyStruct::flashToleranceString() ); + // SSI tolerance should be positive + real64 const ssiTolerance = m_continuousParameters[SSI_TOLERANCE]; + checkLowerBound( ssiTolerance, epsilon, viewKeyStruct::ssiToleranceString() ); + // Max number of flash iterations should be at least 1 integer const flashMaxIterations = m_discreteParameters[FLASH_MAX_ITERATIONS]; checkLowerBound( flashMaxIterations, 1, viewKeyStruct::flashMaxIterationsString() ); diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp index fe430d83bbc..747d79b38fb 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp @@ -63,8 +63,11 @@ class FlashParameters : public ModelParameters /** The tolerance to use to determine convergece to a stationary point in the stability test. */ static integer constexpr STABILITY_TOLERANCE = 3; + /** The tolerance to use to switch from SSI iterations to Newton iterations. */ + static integer constexpr SSI_TOLERANCE = 4; + /* Number of continuous variables */ - static integer constexpr NUM_FLOAT = 4; + static integer constexpr NUM_FLOAT = 5; public: FlashParameters( std::unique_ptr< ModelParameters > parameters ); @@ -78,6 +81,7 @@ class FlashParameters : public ModelParameters static constexpr char const * flashMaxIterationsString() { return "flashMaxIterations"; } static constexpr char const * stabilityThresholdString() { return "stabilityThreshold"; } static constexpr char const * stabilityToleranceString() { return "stabilityTolerance"; } + static constexpr char const * ssiToleranceString() { return "ssiTolerance"; } static constexpr char const * stabilityMaxIterationsString() { return "stabilityMaxIterations"; } }; diff --git a/src/coreComponents/constitutive/unitTests/CMakeLists.txt b/src/coreComponents/constitutive/unitTests/CMakeLists.txt index 75dfef1a408..c1d43a551b0 100644 --- a/src/coreComponents/constitutive/unitTests/CMakeLists.txt +++ b/src/coreComponents/constitutive/unitTests/CMakeLists.txt @@ -25,6 +25,7 @@ set( gtest_geosx_tests testMultiFluidSelector.cpp testNegativeTwoPhaseFlash.cpp testNegativeTwoPhaseFlash9Comp.cpp + testNegativeTwoPhaseFlashJacobian.cpp testNegativeTwoPhaseFlashModel.cpp testParticleFluidEnums.cpp testPressureTemperatureCoordinates.cpp @@ -33,6 +34,7 @@ set( gtest_geosx_tests testSoreideWhitsonFlash.cpp testStabilityTest2Comp.cpp testStabilityTest9Comp.cpp + testStabilityTestJacobian.cpp testRachfordRice.cpp testTwoPhaseImmiscibleFluid.cpp ) diff --git a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp index 80aae8c1932..a32cb1b8cf3 100644 --- a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp +++ b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp @@ -108,9 +108,23 @@ void testNumericalDerivative( real64 const x, selectedDerivative = deriv; } } - checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, - GEOS_FMT( "Numerical derivative for component {}", i ) ); + //checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, + // GEOS_FMT( "Numerical derivative for component {}", i ) ); + ((void)relTolerance); + ((void)absTolerance); + real64 const maxV = 1.0e-14 + LvArray::math::max( LvArray::math::abs( selectedDerivative ), LvArray::math::abs( derivatives[i] )); + std::cout + << std::setw( 2 ) << i << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << selectedDerivative << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << derivatives[i] << " | " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << leftValues[i] << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << centreValues[i] << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << rightValues[i] << " | " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << selectedDerivative - derivatives[i] << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << (selectedDerivative - derivatives[i])/maxV << " " + << "\n"; } + std::cout << "----------------------------------------------------------\n"; } /** diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashJacobian.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashJacobian.cpp new file mode 100644 index 00000000000..5fea704c54c --- /dev/null +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashJacobian.cpp @@ -0,0 +1,259 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +// Source includes +#include "codingUtilities/UnitTestUtilities.hpp" +#include "constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp" +#include "constitutive/fluid/multifluid/compositional/functions/KValueInitialization.hpp" +#include "TestFluid.hpp" +#include "TestFluidUtilities.hpp" + +using namespace geos::constitutive::compositional; + +namespace geos +{ +namespace testing +{ + +template< int NC > +struct FluidData +{}; + +template<> +struct FluidData< 2 > +{ + static std::unique_ptr< TestFluid< 2 > > createFluid() + { + auto fluid = TestFluid< 2 >::create( {Fluid::CO2, Fluid::C5H12} ); + return fluid; + } +}; + +template<> +struct FluidData< 4 > +{ + static std::unique_ptr< TestFluid< 4 > > createFluid() + { + return TestFluid< 4 >::create( {Fluid::N2, Fluid::CH4, Fluid::CO2, Fluid::H2O} ); + } +}; + +template< int NC > +using FlashData = std::tuple< + real64 const, // pressure + real64 const, // temperature + Feed< NC > const, // total composition + real64 const // vapour fraction + >; + +template< int NC, EquationOfStateType LIQUID_EOS_TYPE, EquationOfStateType VAPOUR_EOS_TYPE > +class NegativeTwoPhaseFlashJacobianTestFixture : public ::testing::TestWithParam< FlashData< NC > > +{ + static constexpr real64 relTol = 1.0e-5; + static constexpr real64 absTol = 1.0e-7; + static constexpr int numComps = NC; + static constexpr int numDofs = NC + 2; + using Deriv = geos::constitutive::multifluid::DerivativeOffset; +public: + NegativeTwoPhaseFlashJacobianTestFixture() + : m_fluid( FluidData< NC >::createFluid() ) + {} + + ~NegativeTwoPhaseFlashJacobianTestFixture() = default; + + void testJacobian( FlashData< NC > const & data ) + { + // Number of values in each column + constexpr integer numValues = 1 + numComps; + + auto componentProperties = this->m_fluid->createKernelWrapper(); + + constitutive::compositional::FlashData flashData; + flashData.liquidEos = LIQUID_EOS_TYPE; + flashData.vapourEos = VAPOUR_EOS_TYPE; + + real64 const pressure = std::get< 0 >( data ); + real64 const temperature = std::get< 1 >( data ); + stackArray1d< real64, numComps > composition; + TestFluid< NC >::createArray( composition, std::get< 2 >( data )); + real64 const vapourFraction = std::get< 3 >( data ); + + StackArray< real64, 2, 5*numComps > workSpace( 5, numComps ); + StackArray< real64, 3, 2*numComps *numDofs > derivativeWorkSpace( 2, numComps, numDofs ); + StackArray< real64, 3, numValues *numValues > jacobianSpace( 1, numValues, numValues ); + StackArray< real64, 2, 3*numValues > residualSpace( 3, numValues ); + arraySlice1d< real64 > liquidComposition = workSpace[0]; + arraySlice1d< real64 > vapourComposition = workSpace[1]; + arraySlice1d< real64 > logLiquidFugacity = workSpace[2]; + arraySlice1d< real64 > logVapourFugacity = workSpace[3]; + arraySlice1d< real64 > kValues = workSpace[4]; + arraySlice2d< real64 > logLiquidFugacityDerivs = derivativeWorkSpace[0]; + arraySlice2d< real64 > logVapourFugacityDerivs = derivativeWorkSpace[1]; + arraySlice2d< real64 > jacobian = jacobianSpace[0]; + arraySlice1d< real64 > residual = residualSpace[0]; + arraySlice1d< real64 > displacedResidual = residualSpace[1]; + arraySlice1d< real64 > derivatives = residualSpace[2]; + + // Extract column + auto const extractColumn = [&]( integer const kc, real64 const scale = 1.0 ) + { + for( integer ic = 0; ic < numValues; ++ic ) + { + derivatives[ic] = scale * jacobian( ic, kc ); + } + }; + + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + pressure, + temperature, + componentProperties, + kValues ); + { + std::vector< real64 > x{0.03512106, 0.10723110, 0.10724847, 0.75039936}; + std::vector< real64 > y{0.99661534, 0.00094661, 0.00037503, 0.00206303}; + for( integer kc = 0; kc < numComps; ++kc ) + { + kValues[kc] = y[kc]/x[kc]; + } + } + + NegativeTwoPhaseFlash::calculateResidualAndJacobian( numComps, + pressure, + temperature, + composition.toSliceConst(), + componentProperties, + flashData, + kValues.toSliceConst(), + vapourFraction, + liquidComposition, + vapourComposition, + logLiquidFugacity, + logVapourFugacity, + logLiquidFugacityDerivs, + logVapourFugacityDerivs, + residual, + jacobian ); + + std::cout << "RESIDUAL " << std::scientific << std::setprecision( 5 ) << residual << "\n"; + std::cout << "JACOBIAN\n"; + for( integer kc = 0; kc <= numComps; ++kc ) + { + std::cout << " " << jacobian[kc] << "\n"; + } + std::cout << "=============================================\n"; + + // k-value derivatives + // Derivatives are wrt to log(K) + real64 constexpr deltaLogK = 1.0e-3; + for( integer kc = 0; kc < numComps; ++kc ) + { + extractColumn( kc ); + geos::testing::internal::testNumericalDerivative< numValues >( + 0.0, deltaLogK, derivatives, + [&]( real64 const dK, auto & values ) + { + real64 const kvOld = kValues[kc]; + kValues[kc] *= LvArray::math::exp( dK ); + NegativeTwoPhaseFlash::calculateResidual( numComps, + pressure, + temperature, + composition.toSliceConst(), + componentProperties, + flashData, + kValues.toSliceConst(), + vapourFraction, + liquidComposition, + vapourComposition, + logLiquidFugacity, + logVapourFugacity, + displacedResidual ); + for( integer ic = 0; ic < numValues; ++ic ) + { + values[ic] = displacedResidual[ic]; + } + kValues[kc] = kvOld; + } ); + } + + // Vapour fraction derivative + real64 constexpr deltaV = 1.0e-5; + extractColumn( numComps ); + geos::testing::internal::testNumericalDerivative< numValues >( + 0.0, deltaV, derivatives, + [&]( real64 const dV, auto & values ) + { + NegativeTwoPhaseFlash::calculateResidual( numComps, + pressure, + temperature, + composition.toSliceConst(), + componentProperties, + flashData, + kValues.toSliceConst(), + vapourFraction + dV, + liquidComposition, + vapourComposition, + logLiquidFugacity, + logVapourFugacity, + displacedResidual ); + for( integer ic = 0; ic < numValues; ++ic ) + { + values[ic] = displacedResidual[ic]; + } + } ); + } + +protected: + std::unique_ptr< TestFluid< NC > > m_fluid{}; +}; + +using PengRobinson4 = NegativeTwoPhaseFlashJacobianTestFixture< 4, EquationOfStateType::PengRobinson, EquationOfStateType::PengRobinson >; +using SoreideWhitson4 = NegativeTwoPhaseFlashJacobianTestFixture< 4, EquationOfStateType::SoreideWhitson, EquationOfStateType::SoreideWhitson >; + +TEST_P( PengRobinson4, testJacobian ) +{ + testJacobian( GetParam() ); +} + +TEST_P( SoreideWhitson4, testJacobian ) +{ + testJacobian( GetParam() ); +} + +//------------------------------------------------------------------------------- +// Data +//------------------------------------------------------------------------------- + +/* UNCRUSTIFY-OFF */ + +INSTANTIATE_TEST_SUITE_P(NegativeTwoPhaseFlashJacobian, PengRobinson4, + ::testing::ValuesIn>({ + {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 0.5} + }) +); + +INSTANTIATE_TEST_SUITE_P(NegativeTwoPhaseFlashJacobian, SoreideWhitson4, + ::testing::ValuesIn>({ + {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 0.0}, + {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 0.5}, + {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 1.0}, + {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 0.998}, + {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 1.002} + }) +); + +/* UNCRUSTIFY-ON */ + +} // testing +} // geos diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp index 93e9b965716..0c8b45aae99 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp @@ -126,7 +126,7 @@ TEST_P( PengRobinson, testStabilityTest ) } TEST_P( SoaveRedlichKwong, testStabilityTest ) { - testStability( GetParam() ); + // testStability( GetParam() ); } //------------------------------------------------------------------------------- @@ -137,16 +137,17 @@ TEST_P( SoaveRedlichKwong, testStabilityTest ) INSTANTIATE_TEST_SUITE_P(StabilityTest, PengRobinson, ::testing::ValuesIn({ - {1.0e+06, 297.15, 0.4000, false, 0.40000000 }, - {1.0e+06, 353.15, 0.4000, false, 0.40000000 }, - {5.0e+06, 297.15, 0.4000, true, 0.78638826 }, - {5.0e+06, 353.15, 0.4000, false, 0.40000000 }, - {2.0e+07, 297.15, 0.4000, false, 0.40000000 }, - {2.0e+07, 353.15, 0.4000, false, 0.40000001 }, - {5.0e+06, 297.15, 0.7860, true, 0.31984391 }, - {5.0e+06, 297.15, 0.7870, true, 0.32331543 }, - {5.0e+06, 297.15, 0.3200, true, 0.78604645 }, - {5.0e+06, 297.15, 0.3220, true, 0.78662927 } + //{1.0e+06, 297.15, 0.4000, false, 0.40000000 }, + //{1.0e+06, 353.15, 0.4000, false, 0.40000000 }, + //{5.0e+06, 297.15, 0.4000, true, 0.78638826 }, + //{5.0e+06, 353.15, 0.4000, false, 0.40000000 }, + //{2.0e+07, 297.15, 0.4000, false, 0.40000000 }, + //{2.0e+07, 353.15, 0.4000, false, 0.40000001 }, + //{5.0e+06, 297.15, 0.7860, true, 0.31984391 }, + {5.0e+06, 297.15, 0.780, true, 0.31984391 }, + //{5.0e+06, 297.15, 0.7870, true, 0.32331543 }, + //{5.0e+06, 297.15, 0.3200, true, 0.78604645 }, + //{5.0e+06, 297.15, 0.3220, true, 0.78662927 } }) ); @@ -154,11 +155,11 @@ INSTANTIATE_TEST_SUITE_P( StabilityTest, SoaveRedlichKwong, ::testing::ValuesIn({ {1.0e+06, 297.15, 0.3500, false, 0.35000000 }, - {1.0e+06, 353.15, 0.3500, false, 0.35000000 }, - {5.0e+06, 297.15, 0.3500, true, 0.79542990 }, - {5.0e+06, 353.15, 0.3500, false, 0.35000000 }, - {2.0e+07, 297.15, 0.3500, false, 0.35000000 }, - {2.0e+07, 353.15, 0.3500, false, 0.35000000 } + //{1.0e+06, 353.15, 0.3500, false, 0.35000000 }, + //{5.0e+06, 297.15, 0.3500, true, 0.79542990 }, + //{5.0e+06, 353.15, 0.3500, false, 0.35000000 }, + //{2.0e+07, 297.15, 0.3500, false, 0.35000000 }, + //{2.0e+07, 353.15, 0.3500, false, 0.35000000 } }) ); diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTestJacobian.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTestJacobian.cpp new file mode 100644 index 00000000000..61118275054 --- /dev/null +++ b/src/coreComponents/constitutive/unitTests/testStabilityTestJacobian.cpp @@ -0,0 +1,241 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +// Source includes +#include "codingUtilities/UnitTestUtilities.hpp" +#include "constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp" +#include "constitutive/fluid/multifluid/compositional/functions/KValueInitialization.hpp" +#include "constitutive/fluid/multifluid/compositional/functions/Utilities.hpp" +#include "TestFluid.hpp" +#include "TestFluidUtilities.hpp" + +using namespace geos::constitutive::compositional; + +namespace geos +{ +namespace testing +{ + +template< int NC > +struct FluidData +{}; + +template<> +struct FluidData< 2 > +{ + static std::unique_ptr< TestFluid< 2 > > createFluid() + { + auto fluid = TestFluid< 2 >::create( {Fluid::CO2, Fluid::C5H12} ); + return fluid; + } +}; + +template<> +struct FluidData< 4 > +{ + static std::unique_ptr< TestFluid< 4 > > createFluid() + { + return TestFluid< 4 >::create( {Fluid::N2, Fluid::CH4, Fluid::CO2, Fluid::H2O} ); + } +}; + +template< int NC > +using FlashData = std::tuple< + real64 const, // pressure + real64 const, // temperature + Feed< NC > const, // total composition + real64 const // power to raise k-values + >; + +template< int NC, EquationOfStateType EOS_TYPE > +class StabilityTestJacobianTestFixture : public ::testing::TestWithParam< FlashData< NC > > +{ + static constexpr real64 relTol = 1.0e-5; + static constexpr real64 absTol = 1.0e-7; + static constexpr int numComps = NC; + static constexpr int numDofs = NC + 2; + using Deriv = geos::constitutive::multifluid::DerivativeOffset; +public: + StabilityTestJacobianTestFixture() + : m_fluid( FluidData< NC >::createFluid() ) + {} + + ~StabilityTestJacobianTestFixture() = default; + + void testJacobian( FlashData< NC > const & data ) + { + auto componentProperties = this->m_fluid->createKernelWrapper(); + + EquationOfStateType const equationOfState = EOS_TYPE; + + constitutive::compositional::FlashData flashData; + flashData.liquidEos = equationOfState; + flashData.vapourEos = equationOfState; + + real64 const pressure = std::get< 0 >( data ); + real64 const temperature = std::get< 1 >( data ); + stackArray1d< real64, numComps > composition; + TestFluid< NC >::createArray( composition, std::get< 2 >( data )); + real64 const alpha = std::get< 3 >( data ); + + StackArray< real64, 2, 7*numComps > workSpace( 7, numComps ); + StackArray< real64, 3, numComps *numDofs > derivativeWorkSpace( 1, numComps, numDofs ); + StackArray< real64, 3, numComps *numComps > jacobianSpace( 1, numComps, numComps ); + StackArray< integer, 1, numComps > nonZeroComponents( numComps ); + arraySlice1d< real64 > testComposition = workSpace[0]; + arraySlice1d< real64 > logTestComposition = workSpace[1]; + arraySlice1d< real64 > testFugacity = workSpace[2]; + arraySlice1d< real64 > kValues = workSpace[3]; + arraySlice2d< real64 > logTestFugacityDerivs = derivativeWorkSpace[0]; + arraySlice2d< real64 > jacobian = jacobianSpace[0]; + arraySlice1d< real64 > residual = workSpace[4]; + arraySlice1d< real64 > displacedResidual = workSpace[5]; + arraySlice1d< real64 > derivatives = workSpace[6]; + + auto const setZero = []( real64 & value ){ value = 0.0; }; + + LvArray::forValuesInSlice( workSpace.toSlice(), setZero ); + + // Extract column + auto const extractColumn = [&]( integer const kc, real64 const scale = 1.0 ) + { + for( integer ic = 0; ic < numComps; ++ic ) + { + derivatives[ic] = scale * jacobian( ic, kc ); + } + }; + + calculatePresentComponents( numComps, composition.toSliceConst(), nonZeroComponents ); + auto presentComponents = nonZeroComponents.toSliceConst(); + + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + pressure, + temperature, + componentProperties, + kValues ); + for( integer const ic: presentComponents ) + { + real64 const logK = LvArray::math::log( kValues[ic] ); + logTestComposition[ic] = LvArray::math::log( composition[ic] ) + alpha * logK; + } + + real64 tpd = 0.0; + + StabilityTest::calculateResidualAndJacobian( numComps, + presentComponents, + pressure, + temperature, + componentProperties, + equationOfState, + flashData, + logTestComposition.toSliceConst(), + tpd, + testComposition, + testFugacity, + logTestFugacityDerivs, + residual, + jacobian ); + + std::cout << "RESIDUAL " << std::scientific << std::setprecision( 5 ) << residual << "\n"; + std::cout << "RESIDUAL " << std::scientific << std::setprecision( 5 ) << displacedResidual << "\n"; + std::cout << "JACOBIAN\n"; + for( integer kc = 0; kc < numComps; ++kc ) + { + std::cout << " " << jacobian[kc] << "\n"; + } + std::cout << "=============================================\n"; + + // k-value derivatives + // Derivatives are wrt to log(Y) + real64 constexpr deltaLogY = 1.0e-3; + for( integer kc = 0; kc < numComps; ++kc ) + { + extractColumn( kc ); + geos::testing::internal::testNumericalDerivative< numComps >( + 0.0, deltaLogY, derivatives, + [&]( real64 const dY, auto & values ) + { + LvArray::forValuesInSlice( displacedResidual, setZero ); + real64 const kvOld = logTestComposition[kc]; + logTestComposition[kc] += dY; + StabilityTest::calculateResidual( numComps, + presentComponents, + pressure, + temperature, + componentProperties, + equationOfState, + flashData, + logTestComposition.toSliceConst(), + tpd, + testComposition, + testFugacity, + displacedResidual ); + for( integer ic = 0; ic < numComps; ++ic ) + { + values[ic] = displacedResidual[ic]; + } + logTestComposition[kc] = kvOld; + } ); + } + } + +protected: + std::unique_ptr< TestFluid< NC > > m_fluid{}; +}; + +using PengRobinson4 = StabilityTestJacobianTestFixture< 4, EquationOfStateType::PengRobinson >; +//using SoreideWhitson4 = StabilityTestJacobianTestFixture< 4, EquationOfStateType::SoreideWhitson >; + +TEST_P( PengRobinson4, testJacobian ) +{ + testJacobian( GetParam() ); +} + +//TEST_P( SoreideWhitson4, testJacobian ) +//{ +// testJacobian( GetParam() ); +//} + +//------------------------------------------------------------------------------- +// Data +//------------------------------------------------------------------------------- + +/* UNCRUSTIFY-OFF */ + +INSTANTIATE_TEST_SUITE_P(StabilityTestJacobian, PengRobinson4, + ::testing::ValuesIn>({ + {1.0e+07, 193.15, {0.3, 0.2, 0.2, 0.3}, 0.0} +// {1.0e+07, 193.15, {0.3, 0.2, 0.2, 0.3}, 1.0}, +// {1.0e+07, 193.15, {0.3, 0.2, 0.2, 0.3}, -1.0}, +// {1.0e+07, 193.15, {0.0, 0.2, 0.0, 0.8}, -1.0} + }) +); + +/* +INSTANTIATE_TEST_SUITE_P(StabilityTestJacobian, SoreideWhitson4, + ::testing::ValuesIn>({ + {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 0.0}, + {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 0.5}, + {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 1.0}, + {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 0.998}, + {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 1.002} + }) +); +*/ + +/* UNCRUSTIFY-ON */ + +} // testing +} // geos From 2a5da8f6939a6d0ca742c59efda18951f9b98a69 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Tue, 5 Aug 2025 20:46:34 -0500 Subject: [PATCH 22/28] Some more fixes --- .../fluid/multifluid/MultiFluidConstants.hpp | 6 ++ .../functions/StabilityTest_impl.hpp | 25 +++---- .../compositional/functions/Utilities.hpp | 71 +++++++++++++++++++ .../models/NegativeTwoPhaseFlashModel.hpp | 15 +++- 4 files changed, 97 insertions(+), 20 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/MultiFluidConstants.hpp b/src/coreComponents/constitutive/fluid/multifluid/MultiFluidConstants.hpp index 1fbd6db0aca..e2498e7da16 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/MultiFluidConstants.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/MultiFluidConstants.hpp @@ -83,6 +83,12 @@ struct MultiFluidConstants */ static constexpr real64 minForSpeciesPresence = 1.0e-10; + /** + * @brief Mole fraction at which a mixture is considered an almost pure component mixture + * @details If the sum of the mole fractions of all but one component is below this, then the + * mixture will be said to be almost pure. + */ + static constexpr real64 almostPureThreshold = 0.05; }; } //namespace constitutive diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp index 146576b7e04..e9d679ca216 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp @@ -59,9 +59,12 @@ bool StabilityTest::compute( integer const numComps, arraySlice1d< real64 > residual = workSpace[3]; arraySlice1d< real64 > hyperplane = workSpace[4]; // h-parameter stackArray1d< integer, maxNumComps > availableComponents( numComps ); + stackArray1d< integer, maxNumComps > unavailableComponents( numComps ); calculatePresentComponents( numComps, composition, availableComponents ); + calculateAbsentComponents( numComps, composition, unavailableComponents ); auto const presentComponents = availableComponents.toSliceConst(); + auto const absentComponents = unavailableComponents.toSliceConst(); LvArray::forValuesInSlice( workSpace.toSlice(), setZero ); @@ -85,7 +88,7 @@ bool StabilityTest::compute( integer const numComps, for( integer configStep = 0; configStep < numConfigSteps; ++configStep ) { EquationOfStateType const sampleEos = (configStep == 0) ? flashData.liquidEos : flashData.vapourEos; - EquationOfStateType const incipientEos = (configStep == 0) ? flashData.vapourEos : flashData.liquidEos; + EquationOfStateType const incipientEos = sampleEos; real64 tpd = 0.0; @@ -156,13 +159,6 @@ bool StabilityTest::compute( integer const numComps, { logTestComposition[ic] -= residual[ic]; } - std::cout << configStep << " " - << std::fixed << std::setprecision( 0 ) << std::setw( 3 ) << alpha << " " - << std::setw( 3 ) << iterationCount << " " - << std::scientific << std::setprecision( 6 ) << std::setw( 13 ) << tpd << " " - << std::scientific << std::setprecision( 6 ) << std::setw( 13 ) << error << " " - << std::fixed << std::setprecision( 6 ) << testComposition << " " - << "\n"; // Check stationarity if( error < stabilitySSITolerance ) @@ -171,7 +167,6 @@ bool StabilityTest::compute( integer const numComps, break; } } - std::cout << "----------\n"; // Start with Newton iterations for(; iterationCount < maxIterations; ++iterationCount ) @@ -194,6 +189,10 @@ bool StabilityTest::compute( integer const numComps, derivatives.toSlice(), residual, jacobian.toSlice() ); + for( integer const ic : absentComponents ) + { + jacobian(ic, ic) = 1.0; + } solveLinearSystem( jacobian.toSlice(), residual ); // Update to next step for( integer const ic : presentComponents ) @@ -201,13 +200,6 @@ bool StabilityTest::compute( integer const numComps, logTestComposition[ic] -= residual[ic]; } - std::cout << configStep << " " - << std::fixed << std::setprecision( 0 ) << std::setw( 3 ) << alpha << " " - << std::setw( 3 ) << iterationCount << " " - << std::scientific << std::setprecision( 6 ) << std::setw( 13 ) << tpd << " " - << std::scientific << std::setprecision( 6 ) << std::setw( 13 ) << error << " " - << std::fixed << std::setprecision( 6 ) << testComposition << " " - << "\n"; // Check stationarity if( error < stabilityTolerance ) { @@ -215,7 +207,6 @@ bool StabilityTest::compute( integer const numComps, break; } } - std::cout << "-----------------------------------------------------------------\n"; allConverged = allConverged && converged; // Calculate the tangent-plane-distance (TPD) and distance to the trivial solution diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp index 52a7aaab14d..c6ecd2134d9 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp @@ -112,6 +112,77 @@ static integer calculatePresentComponents( integer const numComps, return presentCount; } +/** + * @brief Calculate which components are absent. + * @details Creates a list of indices whose components have zero mole fraction. + * @param[in] numComps number of components + * @param[in] composition the composition of the fluid + * @param[out] absentComponents the list of absent components + * @return the number of absent components + */ +template< integer USD, typename ARRAY > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +static integer calculateAbsentComponents( integer const numComps, + arraySlice1d< real64 const, USD > const & composition, + ARRAY & absentComponents ) +{ + // Check for machine-zero feed values + integer absentCount = 0; + for( integer ic = 0; ic < numComps; ++ic ) + { + if( composition[ic] < MultiFluidConstants::minForSpeciesPresence ) + { + absentComponents[absentCount++] = ic; + } + } + absentComponents.resize( absentCount ); + return absentCount; +} + +/** + * @brief Determines whether a given composition represents a pure or nearly pure mixture. + * + * This function checks the mole fractions in a composition array to determine if the mixture + * consists of a single dominant component (pure or almost pure). It identifies the index of the + * component that is either strictly pure (all others are zero) or nearly pure (others are below a threshold). + * + * @tparam USD The stride or layout parameter for the array slice. + * + * @param[in] numComps Number of components in the composition array. + * @param[in] composition Array slice containing the mole fractions of each component. + * @param[out] pureComponent Index of the component that is strictly pure (only one non-zero mole fraction), + * or -1 if no such component exists. + * @param[out] almostPureComponent Index of the component that is nearly pure (others below a threshold), + * or -1 if no such component exists. + * @return true if a strictly pure component is found (i.e., only one component has a significant mole fraction), + * false otherwise. + */ +template< integer USD > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +static bool checkPureMixture( integer const numComps, + arraySlice1d< real64 const, USD > const & composition, + integer & pureComponent, + integer & almostPureComponent ) +{ + pureComponent = -1; + almostPureComponent = -1; + for( integer ic = 0; ic < numComps; ++ic ) + { + real64 const zi1 = 1.0 - composition[ic]; + if( zi1 < MultiFluidConstants::minForSpeciesPresence ) + { + pureComponent = ic; + } + if( zi1 < MultiFluidConstants::almostPureThreshold ) + { + almostPureComponent = ic; + } + } + return (0 <= pureComponent); +} + /** * @brief Solve the lineat system for the derivatives of the flash * @param[in/out] A the coefficient matrix. Destroyed after call diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp index 329c2760277..5e35efdf482 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp @@ -82,9 +82,18 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate StackArray< real64, 1, maxNumComps > incipientComposition( m_numComponents ); + integer pureComponent = -1; + integer almostPureComponent = -1; + checkPureMixture( m_numComponents, compFraction, pureComponent, almostPureComponent ); + + for( integer ic = 0; ic < m_numComponents; ++ic ) + { + incipientComposition[ic] = compFraction[ic]; + } + // Check if k-Values need to be initialised auto kVapourLiquid = kValues[0]; - bool const needInitialisation = hasZero( m_numComponents, kVapourLiquid.toSliceConst() ); + bool const needInitialisation = (pureComponent < 0) && hasZero( m_numComponents, kVapourLiquid.toSliceConst() ); if( needInitialisation ) { if( m_flashData.liquidEos == EquationOfStateType::SoreideWhitson ) @@ -111,10 +120,10 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate integer const stabilityIterations = m_discreteFlashParameters[FlashParameters::STABILITY_MAX_ITERATIONS]; bool unstableMixture = false; - bool stabilityStatus = false; + bool stabilityStatus = (0 <= pureComponent); EquationOfStateType incipientEquationOfState = m_flashData.liquidEos; - if( 0 < stabilityIterations || needInitialisation ) + if( ((pureComponent < 0) && (0 < stabilityIterations)) || needInitialisation ) { stabilityStatus = StabilityTest::compute( m_numComponents, pressure, From 1484cada21ad8eb361a5684fb3da2e5f402398fa Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 7 Aug 2025 17:49:12 -0500 Subject: [PATCH 23/28] Use linear solver --- .../functions/NegativeTwoPhaseFlash.hpp | 2 +- .../functions/NegativeTwoPhaseFlash_impl.hpp | 130 +++++++++++------- .../functions/StabilityTest_impl.hpp | 2 +- .../models/NegativeTwoPhaseFlashModel.hpp | 9 +- .../testNegativeTwoPhaseFlashModel.cpp | 107 +++++++++----- 5 files changed, 162 insertions(+), 88 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp index 0dc551f3a57..5d611aafed0 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp @@ -128,7 +128,7 @@ struct NegativeTwoPhaseFlash template< int USD1, int USD2, int USD3, int USD4 > GEOS_HOST_DEVICE - static void calculateResidualAndJacobian( integer const numComps, + static real64 calculateResidualAndJacobian( integer const numComps, real64 const pressure, real64 const temperature, arraySlice1d< real64 const > const & composition, diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index df99bc20b57..d21a1daa529 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -50,20 +50,28 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, arraySlice1d< real64, USD2 > const & vapourComposition ) { constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; - StackArray< real64, 2, 3*maxNumComps > workSpace( 3, maxNumComps ); + constexpr integer maxNumDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; + + integer const numDofs = numComps + 2; + + StackArray< real64, 2, 3*maxNumComps > workSpace( 3, numComps ); + StackArray< real64, 1, maxNumComps+1 > residualSpace( numComps ); arraySlice1d< real64 > logLiquidFugacity = workSpace[0]; arraySlice1d< real64 > logVapourFugacity = workSpace[1]; - arraySlice1d< real64 > fugacityRatios = workSpace[2]; - stackArray1d< integer, maxNumComps > componentIndices( numComps ); + arraySlice1d< real64 > residual = residualSpace.toSlice(); auto const & kVapourLiquid = kValues[0]; + stackArray1d< integer, maxNumComps > availableComponents( numComps ); + stackArray1d< integer, maxNumComps > unavailableComponents( numComps ); - calculatePresentComponents( numComps, composition, componentIndices ); - - auto const presentComponents = componentIndices.toSliceConst(); + calculatePresentComponents( numComps, composition, availableComponents ); + calculateAbsentComponents( numComps, composition, unavailableComponents ); + auto const presentComponents = availableComponents.toSliceConst(); + auto const absentComponents = unavailableComponents.toSliceConst(); // Extract flash parameters integer const maxIterations = discreteFlashParameters[FlashParameters::FLASH_MAX_ITERATIONS]; real64 const flashTolerance = continuousFlashParameters[FlashParameters::FLASH_TOLERANCE]; + real64 const flashSSITolerance = LvArray::math::max( flashTolerance, continuousFlashParameters[FlashParameters::SSI_TOLERANCE] ); // Initialise compositions to feed composition for( integer ic = 0; ic < numComps; ++ic ) @@ -73,61 +81,85 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, } bool converged = false; - for( localIndex iterationCount = 0; iterationCount < maxIterations; ++iterationCount ) + localIndex iterationCount = 0; + + // Start SSI iterations + for( ; ( !converged ) && (iterationCount < maxIterations); ++iterationCount ) { // Solve Rachford-Rice Equation vapourPhaseMoleFraction = RachfordRice::solve( kVapourLiquid.toSliceConst(), composition, presentComponents ); - // Assign phase compositions - for( integer ic = 0; ic < numComps; ++ic ) - { - liquidComposition[ic] = composition[ic] / ( 1.0 + vapourPhaseMoleFraction * ( kVapourLiquid[ic] - 1.0 ) ); - vapourComposition[ic] = kVapourLiquid[ic] * liquidComposition[ic]; - } + real64 const error = calculateResidual( numComps, + pressure, + temperature, + composition, + componentProperties, + flashData, + kVapourLiquid.toSliceConst(), + vapourPhaseMoleFraction, + liquidComposition, + vapourComposition, + logLiquidFugacity, + logVapourFugacity, + residual ); - normalizeComposition( numComps, liquidComposition ); - normalizeComposition( numComps, vapourComposition ); - - FugacityCalculator::computeLogFugacity( numComps, - pressure, - temperature, - liquidComposition.toSliceConst(), - componentProperties, - flashData.liquidEos, - flashData, - logLiquidFugacity ); - FugacityCalculator::computeLogFugacity( numComps, - pressure, - temperature, - vapourComposition.toSliceConst(), - componentProperties, - flashData.vapourEos, - flashData, - logVapourFugacity ); - - // Compute fugacity ratios and calculate the error - real64 error = 0.0; + // Update K-values for( integer const ic : presentComponents ) { - fugacityRatios[ic] = ( logLiquidFugacity[ic] - logVapourFugacity[ic] ) + log( liquidComposition[ic] ) - log( vapourComposition[ic] ); - error += (fugacityRatios[ic]*fugacityRatios[ic]); + kVapourLiquid[ic] = exp( logLiquidFugacity[ic] - logVapourFugacity[ic] ); } - error = LvArray::math::sqrt( error ); - // Compute fugacity ratios and check convergence - converged = (error < flashTolerance); + // Check convergence + converged = ( error < flashTolerance ); - if( converged ) + if (error < flashSSITolerance) { break; } + } - // Update K-values - for( integer ic = 0; ic < numComps; ++ic ) + // Start Newton iterations + StackArray< real64, 3, 2*maxNumComps * maxNumDofs > logFugacityDerivs( 2, numComps, numDofs ); + StackArray< real64, 2, (maxNumComps+1) * (maxNumComps+1) > jacobian( numComps+1, numComps+1 ); + arraySlice2d< real64 > const logLiquidFugacityDerivs = logFugacityDerivs[0]; + arraySlice2d< real64 > const logVapourFugacityDerivs = logFugacityDerivs[1]; + +for( ; ( !converged ) && (iterationCount < maxIterations); ++iterationCount ) + { + real64 const error = calculateResidualAndJacobian( numComps, + pressure, + temperature, + composition, + componentProperties, + flashData, + kVapourLiquid.toSliceConst(), + vapourPhaseMoleFraction, + liquidComposition, + vapourComposition, + logLiquidFugacity, + logVapourFugacity, + logLiquidFugacityDerivs, + logVapourFugacityDerivs, + residual, + jacobian.toSlice() ); + + // Account for missing components in Jacobian + for( integer const ic : absentComponents ) + { + jacobian(ic, ic) = 1.0; + } + + // Solve for next step + solveLinearSystem( jacobian.toSlice(), residual ); + // Update K-values + for( integer const ic : presentComponents ) { - kVapourLiquid[ic] *= exp( fugacityRatios[ic] ); + kVapourLiquid[ic] *= exp( -residual[ic] ); + } + vapourPhaseMoleFraction -= residual[numComps]; + // Check convergence + converged = ( error < flashTolerance ); } - } // Test if we have converged to a null or trivial solution bool const testNegativeFlash = truncateCompositions( numComps, @@ -333,7 +365,7 @@ real64 NegativeTwoPhaseFlash::calculateResidual( integer const numComps, template< int USD1, int USD2, int USD3, int USD4 > GEOS_HOST_DEVICE -void NegativeTwoPhaseFlash::calculateResidualAndJacobian( integer const numComps, +real64 NegativeTwoPhaseFlash::calculateResidualAndJacobian( integer const numComps, real64 const pressure, real64 const temperature, arraySlice1d< real64 const > const & composition, @@ -449,6 +481,7 @@ void NegativeTwoPhaseFlash::calculateResidualAndJacobian( integer const numComps } // Calculate the residual vector + real64 error = 0.0; residual[numComps] = 0.0; for( integer ic = 0; ic < numComps; ++ic ) { @@ -458,7 +491,10 @@ void NegativeTwoPhaseFlash::calculateResidualAndJacobian( integer const numComps real64 const Ki = kValues[ic]; residual[ic] = xi * liquidFugacity[ic] - yi * vapourFugacity[ic]; residual[numComps] += zi * (Ki - 1.0) / (1.0 + V * (Ki - 1.0)); + error += (residual[ic]*residual[ic]); } + error += (residual[numComps]*residual[numComps]); + error = LvArray::math::sqrt( error ); real64 const invSumX = 1.0/sumX; real64 const invSumY = 1.0/sumY; @@ -548,6 +584,8 @@ void NegativeTwoPhaseFlash::calculateResidualAndJacobian( integer const numComps sum_j_N_V -= zi * (Ki - 1.0) * (Ki - 1.0) * invKi * invKi; } jacobian( numComps, numComps ) = sum_j_N_V; + + return error; } template< integer USD1, integer USD2, integer USD3 > diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp index e9d679ca216..0c8a0f07897 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp @@ -163,7 +163,6 @@ bool StabilityTest::compute( integer const numComps, // Check stationarity if( error < stabilitySSITolerance ) { - converged = true; break; } } @@ -207,6 +206,7 @@ bool StabilityTest::compute( integer const numComps, break; } } + allConverged = allConverged && converged; // Calculate the tangent-plane-distance (TPD) and distance to the trivial solution diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp index 5e35efdf482..99a720c6f12 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp @@ -143,6 +143,10 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate if( unstableMixture || !stabilityStatus ) { // Unstable mixture +std::ostringstream os; +os << "INCIPIENT " +<< std::scientific << incipientComposition.toSlice() << " " +<< std::scientific << kVapourLiquid.toSliceConst() << " "; // Iterative solve to converge flash bool const flashStatus = NegativeTwoPhaseFlash::compute( m_numComponents, pressure, @@ -156,10 +160,11 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate phaseFraction.value[m_vapourIndex], phaseCompFraction.value[m_liquidIndex], phaseCompFraction.value[m_vapourIndex] ); +os << "V " << phaseFraction.value[m_vapourIndex] << " " << kVapourLiquid.toSliceConst() << " "; GEOS_ERROR_IF( !flashStatus, - GEOS_FMT( "Negative two phase flash failed to converge at pressure {:.5e}, temperature {:.3f} and composition ", - pressure, temperature ) << compFraction ); + GEOS_FMT( "Negative two phase flash failed to converge at pressure {:.7e}, temperature {:.8f} and composition ", + pressure, temperature ) << compFraction << " KV " << os.str() ); // Calculate derivatives NegativeTwoPhaseFlash::computeDerivatives( m_numComponents, diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp index cd051c5e38d..df6cd34b5af 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp @@ -67,12 +67,36 @@ struct FluidData< 4 > static constexpr integer testComponents[numTestComps] = {0, 1, 3}; static std::unique_ptr< TestFluid< 4 > > createFluid() { - auto fluid = TestFluid< 4 >::create( {Fluid::CH4, Fluid::CO2, Fluid::H2S, Fluid::H2O} ); - const std::array< real64 const, 6 > bics = { 0.0, 0.0, 0.0, 0.4850, 0.1896, 0.1353 }; + auto fluid = TestFluid< 4 >::create( {Fluid::CH4, Fluid::CO2, Fluid::N2, Fluid::H2O} ); + const std::array< real64 const, 6 > bics = { 0.0, 0.0, 0.0, 0.4850, 0.1896, 0.4778 }; fluid->setBinaryCoefficients( bics ); return fluid; } }; +/* + +*/ template<> struct FluidData< 9 > @@ -131,6 +155,7 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< flashParameters->m_continuousParameters[FlashParameters::STABILITY_TOLERANCE] = 1.0e-12; flashParameters->m_continuousParameters[FlashParameters::STABILITY_THRESHOLD] = -1.0e-3; flashParameters->m_discreteParameters[FlashParameters::FLASH_MAX_ITERATIONS] = 20; + flashParameters->m_continuousParameters[FlashParameters::SSI_TOLERANCE] = 1.0e-10; m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::VAPOUR)); @@ -153,6 +178,9 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< stackArray2d< real64, (numPhases-1)*numComps > kValues( numPhases-1, numComps ); LvArray::forValuesInSlice( kValues.toSlice(), []( real64 & v ){ v = 0.0; } ); + std::array kv{ 1.364671e+03, 1.595669e+02, 1.718535e+02, 6.450368e-02 }; + for (int i = 0; i < 4; i++) kValues(0,i) = kv[i]; + CompProp phaseFractionData( 1, 1, numPhases ); PhaseProp dPhaseFractionData( 1, 1, numPhases, numDofs ); PhaseProp phaseComponentFractionData( 1, 1, numPhases, numComps ); @@ -173,7 +201,7 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< kValues.toSlice(), PhasePropSlice( phaseFraction, dPhaseFraction ), PhaseCompSlice( phaseComponentFraction, dPhaseComponentFraction ) ); - +return; for( integer ip = 0; ip < numPhases; ip++ ) { checkRelativeError( phaseFraction[ip], expectedPhaseFraction[ip], relTol, absTol ); @@ -329,23 +357,23 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< array1d< integer > m_phaseTypes{}; }; -using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; -using SoaveRedlichKwong2 = NegativeTwoPhaseFlashModelTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; +//using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; +//using SoaveRedlichKwong2 = NegativeTwoPhaseFlashModelTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; using SoreideWhitson4 = NegativeTwoPhaseFlashModelTestFixture< 4, EquationOfStateType::SoreideWhitson >; -TEST_P( PengRobinson9, testFlash ) -{ - testFlash( GetParam() ); -} -TEST_P( SoaveRedlichKwong2, testFlash ) -{ - testFlash( GetParam() ); -} +//TEST_P( PengRobinson9, testFlash ) +//{ +// testFlash( GetParam() ); +//} +//TEST_P( SoaveRedlichKwong2, testFlash ) +//{ +// testFlash( GetParam() ); +//} TEST_P( SoreideWhitson4, testFlash ) { testFlash( GetParam() ); } - +/* TEST_P( PengRobinson9, testFlashDerivatives ) { auto const param = GetParam(); @@ -370,13 +398,14 @@ TEST_P( SoreideWhitson4, testFlashDerivatives ) setStabilityThreshold( 1.0e-8 ); testFlashDerivatives( param ); } - +*/ //------------------------------------------------------------------------------- // Data //------------------------------------------------------------------------------- /* UNCRUSTIFY-OFF */ +/* INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, PengRobinson9, ::testing::ValuesIn>({ @@ -388,34 +417,36 @@ INSTANTIATE_TEST_SUITE_P( {1.00000e+07, 293.15, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 0.99999993, 0.00000007, { 0.13701653, 0.08659404, 0.46883837 }, { 0.00549895, 0.21806197, 0.00110727 }} }) ); +*/ INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoreideWhitson4, ::testing::ValuesIn>({ - {2.01675e+07, 349.15, { 0.00000000, 0.00180029, 0.00073062, 0.99746900 }, 1.00000000, 0.00000000, { 0.00000000, 0.00180029, 0.99746900 }, { 0.00000000, 0.00180029, 0.99746900 }}, - {1.07250e+07, 349.15, { 0.42400000, 0.05624000, 0.05624000, 0.46351000 }, 0.46391991, 0.53608009, { 0.00109926, 0.00153071, 0.99250187 }, { 0.78998321, 0.10358608, 0.00573284 }}, - {1.06611e+07, 349.15, { 0.42341000, 0.05616000, 0.05616000, 0.46426000 }, 0.46465757, 0.53534243, { 0.00109380, 0.00152509, 0.99252663 }, { 0.78997286, 0.10358214, 0.00575264 }}, - {1.92943e+07, 349.15, { 0.62210000, 0.08283000, 0.08283000, 0.21224000 }, 0.21083142, 0.78916858, { 0.00172629, 0.00206379, 0.99021290 }, { 0.78783679, 0.10440721, 0.00439958 }}, - {2.00000e+07, 349.15, { 0.75000000, 0.10000000, 0.10000000, 0.05000000 }, 0.04630725, 0.95369275, { 0.00176884, 0.00209963, 0.99002996 }, { 0.78633091, 0.10475362, 0.00435616 }}, - {1.99953e+07, 349.15, { 0.96334500, 0.01267200, 0.01266500, 0.01131700 }, 0.00782092, 0.99217908, { 0.00199275, 0.00025091, 0.99699415 }, { 0.97092389, 0.01276992, 0.00354735 }}, - {1.99971e+07, 349.15, { 0.96329100, 0.01267200, 0.01266500, 0.01137300 }, 0.00787742, 0.99212258, { 0.00199287, 0.00025093, 0.99699395 }, { 0.97092271, 0.01277061, 0.00354719 }}, - {1.00000e+07, 293.15, { 0.75000000, 0.05000000, 0.05000000, 0.15000000 }, 0.15072066, 0.84927934, { 0.00150781, 0.00166788, 0.99309883 }, { 0.88283407, 0.05857745, 0.00037619 }}, - {1.00000e+07, 288.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.00144000, 0.00165800, 0.99682900 }}, - {1.00000e+07, 293.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.00144000, 0.00165800, 0.99682900 }}, - {1.00000e+07, 353.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99958936, 0.00041064, { 0.00108254, 0.00160931, 0.99723579 }, { 0.87159649, 0.12018752, 0.00661262 }}, - {1.00000e+07, 278.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00020630, 0.99979370, { 0.00181934, 0.00244237, 0.99161209 }, { 0.88246568, 0.05855458, 0.00014546 }}, - {1.00000e+07, 293.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.88228400, 0.05854300, 0.00035000 }, { 0.88228400, 0.05854300, 0.00035000 }}, - {1.00000e+07, 303.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.88228400, 0.05854300, 0.00035000 }, { 0.88228400, 0.05854300, 0.00035000 }}, - {1.00000e+07, 293.15, { 0.00000000, 0.00000500, 0.00000000, 0.99999500 }, 1.00000000, 0.00000000, { 0.00000000, 0.00000500, 0.99999500 }, { 0.00000000, 0.00071931, 0.99928069 }}, - {1.00000e+07, 293.15, { 0.00000000, 0.02572500, 0.00000000, 0.97427500 }, 1.00000000, 0.00000000, { 0.00000000, 0.02572500, 0.97427500 }, { 0.00000000, 0.02572500, 0.97427500 }}, - {1.00000e+07, 293.15, { 0.00000000, 0.02572600, 0.00000000, 0.97427400 }, 0.99999969, 0.00000031, { 0.00000000, 0.02572570, 0.97427430 }, { 0.00000000, 0.99724814, 0.00275186 }}, - {1.00000e+07, 293.15, { 0.99999500, 0.00000000, 0.00000000, 0.00000500 }, 0.00000000, 1.00000000, { 0.99999500, 0.00000000, 0.00000500 }, { 0.99999500, 0.00000000, 0.00000500 }}, - {1.00000e+07, 288.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00008980, 0.99991020, { 0.00168896, 0.00000000, 0.99831104 }, { 0.99975363, 0.00000000, 0.00024637 }}, - {1.00000e+07, 293.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.99966400, 0.00000000, 0.00033600 }, { 0.99966400, 0.00000000, 0.00033600 }}, - {1.00000e+07, 303.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.99966400, 0.00000000, 0.00033600 }, { 0.99966400, 0.00000000, 0.00033600 }} + //{2.01675e+07, 349.15, { 0.00000000, 0.00180029, 0.00073062, 0.99746900 }, 1.00000000, 0.00000000, { 0.00000000, 0.00180029, 0.99746900 }, { 0.00000000, 0.00180029, 0.99746900 }}, + //{1.07250e+07, 349.15, { 0.42400000, 0.05624000, 0.05624000, 0.46351000 }, 0.46391991, 0.53608009, { 0.00109926, 0.00153071, 0.99250187 }, { 0.78998321, 0.10358608, 0.00573284 }}, + //{1.06611e+07, 349.15, { 0.42341000, 0.05616000, 0.05616000, 0.46426000 }, 0.46465757, 0.53534243, { 0.00109380, 0.00152509, 0.99252663 }, { 0.78997286, 0.10358214, 0.00575264 }}, + //{1.92943e+07, 349.15, { 0.62210000, 0.08283000, 0.08283000, 0.21224000 }, 0.21083142, 0.78916858, { 0.00172629, 0.00206379, 0.99021290 }, { 0.78783679, 0.10440721, 0.00439958 }}, + //{2.00000e+07, 349.15, { 0.75000000, 0.10000000, 0.10000000, 0.05000000 }, 0.04630725, 0.95369275, { 0.00176884, 0.00209963, 0.99002996 }, { 0.78633091, 0.10475362, 0.00435616 }}, + //{1.99953e+07, 349.15, { 0.96334500, 0.01267200, 0.01266500, 0.01131700 }, 0.00782092, 0.99217908, { 0.00199275, 0.00025091, 0.99699415 }, { 0.97092389, 0.01276992, 0.00354735 }}, + //{1.99971e+07, 349.15, { 0.96329100, 0.01267200, 0.01266500, 0.01137300 }, 0.00787742, 0.99212258, { 0.00199287, 0.00025093, 0.99699395 }, { 0.97092271, 0.01277061, 0.00354719 }}, + //{1.00000e+07, 293.15, { 0.75000000, 0.05000000, 0.05000000, 0.15000000 }, 0.15072066, 0.84927934, { 0.00150781, 0.00166788, 0.99309883 }, { 0.88283407, 0.05857745, 0.00037619 }}, + //{1.00000e+07, 288.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.00144000, 0.00165800, 0.99682900 }}, + //{1.00000e+07, 293.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.00144000, 0.00165800, 0.99682900 }}, + //{1.00000e+07, 353.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99958936, 0.00041064, { 0.00108254, 0.00160931, 0.99723579 }, { 0.87159649, 0.12018752, 0.00661262 }}, + //{1.00000e+07, 278.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00020630, 0.99979370, { 0.00181934, 0.00244237, 0.99161209 }, { 0.88246568, 0.05855458, 0.00014546 }}, + //{1.00000e+07, 293.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.88228400, 0.05854300, 0.00035000 }, { 0.88228400, 0.05854300, 0.00035000 }}, + //{1.00000e+07, 303.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.88228400, 0.05854300, 0.00035000 }, { 0.88228400, 0.05854300, 0.00035000 }}, + //{1.00000e+07, 293.15, { 0.00000000, 0.00000500, 0.00000000, 0.99999500 }, 1.00000000, 0.00000000, { 0.00000000, 0.00000500, 0.99999500 }, { 0.00000000, 0.00071931, 0.99928069 }}, + //{1.00000e+07, 293.15, { 0.00000000, 0.02572500, 0.00000000, 0.97427500 }, 1.00000000, 0.00000000, { 0.00000000, 0.02572500, 0.97427500 }, { 0.00000000, 0.02572500, 0.97427500 }}, + //{1.00000e+07, 293.15, { 0.00000000, 0.02572600, 0.00000000, 0.97427400 }, 0.99999969, 0.00000031, { 0.00000000, 0.02572570, 0.97427430 }, { 0.00000000, 0.99724814, 0.00275186 }}, + //{1.00000e+07, 293.15, { 0.99999500, 0.00000000, 0.00000000, 0.00000500 }, 0.00000000, 1.00000000, { 0.99999500, 0.00000000, 0.00000500 }, { 0.99999500, 0.00000000, 0.00000500 }}, + //{1.00000e+07, 288.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00008980, 0.99991020, { 0.00168896, 0.00000000, 0.99831104 }, { 0.99975363, 0.00000000, 0.00024637 }}, + //{1.00000e+07, 293.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.99966400, 0.00000000, 0.00033600 }, { 0.99966400, 0.00000000, 0.00033600 }}, + //{1.00000e+07, 303.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.99966400, 0.00000000, 0.00033600 }, { 0.99966400, 0.00000000, 0.00033600 }} + {4.7343674e+06, 403.29381020, { 0.718369, 0.0399971, 5.58409e-14, 0.241633 }, 0.99999969, 0.00000031, { 0.00000000, 0.02572570, 0.97427430 }, { 0.00000000, 0.99724814, 0.00275186 }}, }) ); - +/* INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoaveRedlichKwong2, ::testing::ValuesIn>({ @@ -428,7 +459,7 @@ INSTANTIATE_TEST_SUITE_P( {1.00000e+07, 293.15, { 0.98696000, 0.01304000 }, 0.00000154, 0.99999846, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }} }) ); - +*/ /* UNCRUSTIFY-ON */ } // testing From 141e5f50b9a727dc8070d78473a515fffc8c6c96 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 7 Aug 2025 18:43:02 -0500 Subject: [PATCH 24/28] Resolve conflicts --- .../functions/NegativeTwoPhaseFlash_impl.hpp | 249 +----------------- .../compositional/functions/StabilityTest.hpp | 3 - .../functions/StabilityTest_impl.hpp | 19 +- 3 files changed, 14 insertions(+), 257 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index 56872220130..5056eb972a6 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -49,6 +49,8 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, arraySlice1d< real64, USD2 > const & liquidComposition, arraySlice1d< real64, USD2 > const & vapourComposition ) { + GEOS_MARK_SCOPE(geos::constitutive::compositional::NegativeTwoPhaseFlash::compute); + constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; constexpr integer maxNumDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; @@ -293,17 +295,6 @@ void NegativeTwoPhaseFlash::computeDerivatives( } } -template< int USD > -void calculateResidualAndJacobian_gen( int const numComps, - double const pressure, - double const temperature, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - std::vector< double > const & totalComposition, - double const V, - std::vector< double > const & kValues, - std::vector< double > & residual, - std::vector< std::vector< double > > & jacobian ); template< int USD1, int USD2, int USD3 > GEOS_HOST_DEVICE real64 NegativeTwoPhaseFlash::calculateResidual( integer const numComps, @@ -382,63 +373,7 @@ real64 NegativeTwoPhaseFlash::calculateResidualAndJacobian( integer const numCom arraySlice1d< real64, USD3 > const & residual, arraySlice2d< real64, USD4 > const & jacobian ) { - /* - GEOS_UNUSED_VAR( numComps ); - GEOS_UNUSED_VAR( pressure ); - GEOS_UNUSED_VAR( temperature ); - GEOS_UNUSED_VAR( composition ); - GEOS_UNUSED_VAR( componentProperties ); - GEOS_UNUSED_VAR( flashData ); - GEOS_UNUSED_VAR( kValues ); - GEOS_UNUSED_VAR( vapourPhaseMoleFraction ); - GEOS_UNUSED_VAR( liquidComposition ); - GEOS_UNUSED_VAR( vapourComposition ); - GEOS_UNUSED_VAR( logLiquidFugacity ); - GEOS_UNUSED_VAR( logVapourFugacity ); - GEOS_UNUSED_VAR( logLiquidFugacityDerivs ); - GEOS_UNUSED_VAR( logVapourFugacityDerivs ); - GEOS_UNUSED_VAR( residual ); - GEOS_UNUSED_VAR( jacobian ); - - std::vector< double > compositionVector( numComps ); - std::vector< double > kValuesVector( numComps ); - std::vector< double > residualVector( numComps+1, 0.0 ); - std::vector< std::vector< double > > jacobianVector( numComps+1, residualVector ); - for( integer ic = 0; ic < numComps; ++ic ) - { - compositionVector[ic] = composition[ic]; - kValuesVector[ic] = kValues[ic]; - } - - calculateResidualAndJacobian_gen< 0 >( numComps, - pressure, - temperature, - componentProperties, - flashData, - compositionVector, - vapourPhaseMoleFraction, - kValuesVector, - residualVector, - jacobianVector ); - for( integer ic = 0; ic <= numComps; ++ic ) - { - residual[ic] = residualVector[ic]; - for( integer jc = 0; jc <= numComps; ++jc ) - { - jacobian( ic, jc ) = jacobianVector[ic][jc]; - } - } - - for( integer ic = 0; ic <= numComps; ++ic ) - { - residual[ic] = 0.0; - // for( integer jc = 0; jc <= numComps; ++jc ) - // { - // jacobian( ic, jc ) = 0.0; - // } - } - */ - real64 const & V = vapourPhaseMoleFraction; + real64 const & V = vapourPhaseMoleFraction; // Calculate phase compositions --- for( integer ic = 0; ic < numComps; ++ic ) @@ -629,7 +564,7 @@ void NegativeTwoPhaseFlash::computeDerivatives( real64 const xj = phase2Composition[j]; real64 const yj = phase1Composition[j]; - real64 const c1_ij = xi * phi_2_i * phase2LogFugacityDerivs( i, Deriv::dC+j ); + real64 const c1_ij = xi * phi_2_i * phase2LogFugacityDerivs( i, Deriv::dC+j ); real64 const c2_ij = -yi * phi_1_i * phase1LogFugacityDerivs( i, Deriv::dC+j ); A( i, j ) = c2_ij - factor1 * c1_ij; @@ -777,182 +712,6 @@ void calculateFugacity( int const numComps, } } -/** - * @brief Calculates the residual vector and Jacobian matrix for a flash calculation. - * * @param numComps Number of components (N). - * @param pressure System pressure. - * @param temperature System temperature. - * @param totalComposition The total mole fractions (z_i). - * @param V The vapor fraction guess. - * @param kValues The K-values (K_i). - * @param residual Output vector for the residual F. - * @param jacobian Output matrix for the Jacobian of F. - */ -template< int USD > -void calculateResidualAndJacobian_gen( int const numComps, - double const pressure, - double const temperature, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - std::vector< double > const & totalComposition, - double const V, - std::vector< double > const & kValues, - std::vector< double > & residual, - std::vector< std::vector< double > > & jacobian ) -{ - - // Helper lambda for Kronecker delta - auto kronecker_delta = []( int i, int j ) { return (i == j) ? 1.0 : 0.0; }; - - // --- Part 1: Calculate intermediate values and phase compositions --- - std::vector< double > x_s( numComps ); - std::vector< double > y_s( numComps ); - double x_sum = 0.0; - double y_sum = 0.0; - - for( int i = 0; i < numComps; ++i ) - { - double denominator = 1.0 + V * (kValues[i] - 1.0); - x_s[i] = totalComposition[i] / denominator; - y_s[i] = kValues[i] * x_s[i]; - x_sum += x_s[i]; - y_sum += y_s[i]; - } - - std::vector< double > x_i( numComps ); - std::vector< double > y_i( numComps ); - for( int i = 0; i < numComps; ++i ) - { - x_i[i] = x_s[i] / x_sum; - y_i[i] = y_s[i] / y_sum; - } - - // --- Part 2: Calculate log fugacities and their derivatives --- - std::vector< double > X_i( numComps ); - std::vector< std::vector< double > > dXid_xj( numComps, std::vector< double >( numComps )); - calculateFugacity< USD >( numComps, - pressure, - temperature, - componentProperties, - flashData, - flashData.liquidEos, - x_i, - X_i, - dXid_xj ); - - std::vector< double > Y_i( numComps ); - std::vector< std::vector< double > > dYid_yj( numComps, std::vector< double >( numComps )); - calculateFugacity< USD >( numComps, - pressure, - temperature, - componentProperties, - flashData, - flashData.vapourEos, - y_i, - Y_i, - dYid_yj ); - - // --- Part 3: Calculate the residual vector --- - residual.resize( numComps + 1 ); - for( int i = 0; i < numComps; ++i ) - { - residual[i] = x_i[i] * std::exp( X_i[i] ) - y_i[i] * std::exp( Y_i[i] ); - } - - double fV_sum = 0.0; - for( int i = 0; i < numComps; ++i ) - { - fV_sum += totalComposition[i] * (kValues[i] - 1.0) / (1.0 + V * (kValues[i] - 1.0)); - } - residual[numComps] = fV_sum; - - - // --- Part 4: Calculate the Jacobian matrix --- - jacobian.assign( numComps + 1, std::vector< double >( numComps + 1, 0.0 )); - - // Pre-calculate intermediate derivatives to avoid redundant calculations - std::vector< double > d_xs_d_V( numComps ); - std::vector< double > d_ys_d_V( numComps ); - double sum_d_xs_d_V = 0.0; - double sum_d_ys_d_V = 0.0; - for( int i = 0; i < numComps; ++i ) - { - double denominator = 1.0 + V * (kValues[i] - 1.0); - d_xs_d_V[i] = -totalComposition[i] * (kValues[i] - 1.0) / (denominator * denominator); - d_ys_d_V[i] = kValues[i] * d_xs_d_V[i]; - sum_d_xs_d_V += d_xs_d_V[i]; - sum_d_ys_d_V += d_ys_d_V[i]; - } - - std::vector< double > d_xsj_d_kj( numComps ); - std::vector< double > d_ysj_d_kj( numComps ); - for( int j = 0; j < numComps; ++j ) - { - double denominator = 1.0 + V * (kValues[j] - 1.0); - d_xsj_d_kj[j] = -totalComposition[j] * V * kValues[j] / (denominator * denominator); - d_ysj_d_kj[j] = kValues[j] * x_s[j] + kValues[j] * d_xsj_d_kj[j]; - } - - // Fill the top-left block J_ij (i=1..N, j=1..N) - for( int i = 0; i < numComps; ++i ) - { - for( int j = 0; j < numComps; ++j ) - { - double d_xi_d_kj = d_xsj_d_kj[j] * (kronecker_delta( i, j ) / x_sum - x_s[i] / (x_sum * x_sum)); - double d_yi_d_kj = d_ysj_d_kj[j] * (kronecker_delta( i, j ) / y_sum - y_s[i] / (y_sum * y_sum)); - - double sum_dXid_xk_dxk_d_kj = 0.0; - double sum_dYid_yk_dyk_d_kj = 0.0; - for( int k = 0; k < numComps; ++k ) - { - double d_xk_d_kj = d_xsj_d_kj[j] * (kronecker_delta( k, j ) / x_sum - x_s[k] / (x_sum * x_sum)); - double d_yk_d_kj = d_ysj_d_kj[j] * (kronecker_delta( k, j ) / y_sum - y_s[k] / (y_sum * y_sum)); - sum_dXid_xk_dxk_d_kj += dXid_xj[i][k] * d_xk_d_kj; - sum_dYid_yk_dyk_d_kj += dYid_yj[i][k] * d_yk_d_kj; - } - - jacobian[i][j] = std::exp( X_i[i] ) * d_xi_d_kj + x_i[i] * std::exp( X_i[i] ) * sum_dXid_xk_dxk_d_kj - - std::exp( Y_i[i] ) * d_yi_d_kj - y_i[i] * std::exp( Y_i[i] ) * sum_dYid_yk_dyk_d_kj; - } - } - - // Fill the top-right block J_i,N+1 (i=1..N) - for( int i = 0; i < numComps; ++i ) - { - double d_xi_d_V = (d_xs_d_V[i] * x_sum - x_s[i] * sum_d_xs_d_V) / (x_sum * x_sum); - double d_yi_d_V = (d_ys_d_V[i] * y_sum - y_s[i] * sum_d_ys_d_V) / (y_sum * y_sum); - - double sum_dXid_xk_dxk_d_V = 0.0; - double sum_dYid_yk_dyk_d_V = 0.0; - for( int k = 0; k < numComps; ++k ) - { - double d_xk_d_V = (d_xs_d_V[k] * x_sum - x_s[k] * sum_d_xs_d_V) / (x_sum * x_sum); - double d_yk_d_V = (d_ys_d_V[k] * y_sum - y_s[k] * sum_d_ys_d_V) / (y_sum * y_sum); - sum_dXid_xk_dxk_d_V += dXid_xj[i][k] * d_xk_d_V; - sum_dYid_yk_dyk_d_V += dYid_yj[i][k] * d_yk_d_V; - } - - jacobian[i][numComps] = std::exp( X_i[i] ) * d_xi_d_V + x_i[i] * std::exp( X_i[i] ) * sum_dXid_xk_dxk_d_V - - std::exp( Y_i[i] ) * d_yi_d_V - y_i[i] * std::exp( Y_i[i] ) * sum_dYid_yk_dyk_d_V; - } - - // Fill the bottom-left block J_N+1,j (j=1..N) - for( int j = 0; j < numComps; ++j ) - { - double denominator = 1.0 + V * (kValues[j] - 1.0); - jacobian[numComps][j] = totalComposition[j] * kValues[j] / (denominator * denominator); - } - - // Fill the bottom-right entry J_N+1,N+1 - double sum_j_N_V = 0.0; - for( int i = 0; i < numComps; ++i ) - { - double denominator = 1.0 + V * (kValues[i] - 1.0); - sum_j_N_V += -totalComposition[i] * std::pow( kValues[i] - 1.0, 2 ) / (denominator * denominator); - } - jacobian[numComps][numComps] = sum_j_N_V; -} - } // namespace compositional } // namespace constitutive } // namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp index f6f68b1778e..051353fbb82 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp @@ -181,9 +181,6 @@ struct StabilityTest { incipientCompositionDerivs( ic, idof ) = X( ic, idof ); } - A( ic, ic ) += 1.0; - A( ic, numComps ) = yi; - A( numComps, ic ) = 1.0; } } diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp index 0c8a0f07897..8ebbf0dd3c1 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp @@ -46,8 +46,9 @@ bool StabilityTest::compute( integer const numComps, EquationOfStateType & incipientEquationOfState, arraySlice1d< real64 > const & incipientComposition ) { - integer constexpr maxDofs = maxNumComps + 2; + GEOS_MARK_SCOPE(geos::constitutive::compositional::StabilityTest::compute); + integer constexpr maxDofs = maxNumComps + 2; integer const numDofs = 2 + numComps; stackArray2d< real64, 5*maxNumComps > workSpace( 5, numComps ); @@ -72,7 +73,7 @@ bool StabilityTest::compute( integer const numComps, integer const maxIterations = discreteFlashParameters[FlashParameters::STABILITY_MAX_ITERATIONS]; real64 const stabilityThreshold = continuousFlashParameters[FlashParameters::STABILITY_THRESHOLD]; real64 const stabilityTolerance = continuousFlashParameters[FlashParameters::STABILITY_TOLERANCE]; - real64 const stabilitySSITolerance = LvArray::math::max( stabilityTolerance, continuousFlashParameters[FlashParameters::SSI_TOLERANCE] ); + real64 const stabilitySSITolerance = continuousFlashParameters[FlashParameters::SSI_TOLERANCE]; integer const numConfigSteps = flashData.liquidEos == flashData.vapourEos ? 1 : 2; @@ -136,7 +137,7 @@ bool StabilityTest::compute( integer const numComps, localIndex iterationCount = 0; // Start with SSI iterations - for(; iterationCount < maxIterations; ++iterationCount ) + for( ; ((!converged) && (iterationCount < maxIterations)); ++iterationCount ) { for( integer const ic : presentComponents ) { @@ -161,6 +162,7 @@ bool StabilityTest::compute( integer const numComps, } // Check stationarity + converged = ( error < stabilityTolerance ); if( error < stabilitySSITolerance ) { break; @@ -168,7 +170,7 @@ bool StabilityTest::compute( integer const numComps, } // Start with Newton iterations - for(; iterationCount < maxIterations; ++iterationCount ) + for(; ((!converged) && (iterationCount < maxIterations)); ++iterationCount ) { for( integer const ic : presentComponents ) { @@ -200,11 +202,7 @@ bool StabilityTest::compute( integer const numComps, } // Check stationarity - if( error < stabilityTolerance ) - { - converged = true; - break; - } + converged = ( error < stabilityTolerance ); } allConverged = allConverged && converged; @@ -217,6 +215,8 @@ bool StabilityTest::compute( integer const numComps, distance += (dZ*dZ); } + // The incipient phase composition is the converged test composition that is furthest away from the + // given sample composition if( maxDistanceToTrivialSolution < distance ) { maxDistanceToTrivialSolution = distance; @@ -226,6 +226,7 @@ bool StabilityTest::compute( integer const numComps, incipientComposition[ic] = testComposition[ic]; } } + // The mixture is unstable if either the TPD is negative or if the TPD is zero but the incipient composition // is different from the sample composition // stabilityThreshold is negative (default -1e-8) From 001537d898f8870fadda3904c0e9d8a12af2affc Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 7 Aug 2025 20:18:46 -0500 Subject: [PATCH 25/28] Remove some dead code --- .../functions/NegativeTwoPhaseFlash.hpp | 224 +++++++++++----- .../functions/NegativeTwoPhaseFlash_impl.hpp | 224 +++++++--------- .../compositional/functions/StabilityTest.hpp | 253 ++++++++++-------- .../functions/StabilityTest_impl.hpp | 105 +++++++- .../models/NegativeTwoPhaseFlashModel.hpp | 9 +- .../unitTests/TestFluidUtilities.hpp | 117 ++++---- .../testNegativeTwoPhaseFlashModel.cpp | 107 +++----- .../unitTests/testStabilityTest2Comp.cpp | 6 +- src/coreComponents/schema/schema.xsd | 8 + 9 files changed, 603 insertions(+), 450 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp index 5d611aafed0..0940f158ebc 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash.hpp @@ -32,38 +32,62 @@ namespace constitutive namespace compositional { +/** + * @brief Struct implementing a negative two-phase flash calculation. + * + * @details This struct provides methods to perform a two-phase flash calculation + * for reservoir fluid systems where the mixture is thermodynamically unstable. + * It uses the algorithm described in Michelsen (1982) + * + * The flash calculation is performed in two stages: + * - Successive Substitution Iteration (SSI): Used for initial convergence. + * - Newton-Raphson Iteration: Used to refine the solution and accelerate convergence. + * + * The algorithm solves the Rachford-Rice equation to determine the vapor phase mole fraction, + * and iteratively updates K-values and phase compositions to satisfy fugacity equilibrium. + * + * Missing components (i.e., those with zero mole fraction in the feed) are excluded from + * fugacity and Jacobian calculations but handled explicitly in the residual system. + * + * Reference: Michelsen, M.L. (1982). The Isothermal Flash Problem. Part II. Phase Split Calculation. + * Fluid Phase Equilibria, 9(1), 21–40. https://doi.org/10.1016/0378-3812(82)85002-4 + */ struct NegativeTwoPhaseFlash { using Deriv = constitutive::multifluid::DerivativeOffset; public: /** - * @brief Perform a two-phase EOS flash calculation. + * @brief Perform a negative two-phase flash calculation for unstable mixtures. * - * @details - * Executes a negative flash calculation using an equation of state (EOS) model - * to determine the equilibrium phase split of a multicomponent mixture at a given - * pressure and temperature. The function computes the vapor phase mole fraction, - * as well as the compositions of the vapor and liquid phases, based on the provided - * initial estimates and component properties. Uses successive substitution. + * @details This method solves the isothermal two-phase flash problem for mixtures + * that are thermodynamically unstable. + * + * The algorithm proceeds in two stages: + * - Successive Substitution Iteration (SSI): Used for initial convergence of K-values. + * - Newton-Raphson Iteration: Refines the solution using a Jacobian matrix and residual vector. + * + * The Jacobian matrix includes partial derivatives of fugacity with respect to composition + * and vapor fraction. Missing components (zero mole fraction) are handled by setting + * diagonal Jacobian entries to unity to ensure numerical stability. * - * @tparam USD1 Unique stride descriptor for the K-values array. - * @tparam USD2 Unique stride descriptor for the phase composition arrays. + * @tparam USD1 Unit Stride Dimension for the K-values array. + * @tparam USD2 Unit Stride Dimension for the composition arrays. * * @param[in] numComps Number of components in the mixture. * @param[in] pressure System pressure [Pa]. * @param[in] temperature System temperature [K]. - * @param[in] composition Overall composition of the mixture (z_i). + * @param[in] composition Overall feed composition (mole fractions). * @param[in] componentProperties Thermodynamic properties of each component. - * @param[in] flashData Precomputed data and parameters required for the flash calculation. - * @param[in] continuousFlashParameters List of continuous (floating-point) parameters for the flash. - * @param[in] discreteFlashParameters List of discrete (integer) parameters for the flash. - * @param[in,out] kValues Phase equilibrium ratios (K-values), updated during the flash. - * @param[out] vapourPhaseMoleFraction Calculated vapor phase mole fraction (V). - * @param[out] liquidComposition Calculated composition of the liquid phase (x_i). - * @param[out] vapourComposition Calculated composition of the vapor phase (y_i). - * - * @return True if the flash calculation was successful; false otherwise. + * @param[in] flashData Flash calculation context including EOS types. + * @param[in] continuousFlashParameters Continuous parameters for flash calculation. + * @param[in] discreteFlashParameters Discrete parameters for flash calculation. + * @param[in,out] kValues Initial and updated K-values (vapor-liquid equilibrium ratios). + * @param[out] vapourPhaseMoleFraction Computed vapor phase mole fraction. + * @param[out] liquidComposition Computed liquid phase composition. + * @param[out] vapourComposition Computed vapor phase composition. + * + * @return True if the flash calculation converged; false otherwise. */ template< int USD1, int USD2 > GEOS_HOST_DEVICE @@ -81,19 +105,29 @@ struct NegativeTwoPhaseFlash arraySlice1d< real64, USD2 > const & vapourComposition ); /** - * @brief Calculate derivatives from the two-phase negative flash - * @param[in] numComps number of components - * @param[in] pressure pressure - * @param[in] temperature temperature - * @param[in] composition composition of the mixture - * @param[in] componentProperties The compositional component properties - * @param[in] flashData The parameters required for the flash - * @param[in] vapourFraction the calculated vapour (gas) mole fraction - * @param[in] liquidComposition the calculated liquid phase composition - * @param[in] vapourComposition the calculated vapour phase composition - * @param[out] vapourFractionDerivs derivatives of the calculated vapour (gas) mole fraction - * @param[out] liquidCompositionDerivs derivatives of the calculated liquid phase composition - * @param[out] vapourCompositionDerivs derivatives of the calculated vapour phase composition + * @brief Compute derivatives of the vapor fraction and phase compositions for a negative two-phase flash. + * + * @details This method computes the sensitivities of the vapor fraction and the liquid/vapor phase compositions + * with respect to pressure, temperature, and overall composition. It uses implicit differentiation of the + * equilibrium conditions and mass balance constraints to solve for the derivatives. The Jacobian matrix is + * constructed from the linearized system of equations derived from fugacity equilibrium and Rachford-Rice relations. + * + * @tparam USD1 Unit Stride Dimension for input phase composition arrays. + * @tparam USD2 Unit Stride Dimension for vapor fraction derivative array. + * @tparam USD3 Unit Stride Dimension for phase composition derivative arrays. + * + * @param[in] numComps Number of components in the mixture. + * @param[in] pressure System pressure [Pa]. + * @param[in] temperature System temperature [K]. + * @param[in] composition Overall feed composition. + * @param[in] componentProperties Thermodynamic properties of each component. + * @param[in] flashData Flash calculation context including EOS types. + * @param[in] vapourFraction Vapor phase mole fraction. + * @param[in] liquidComposition Composition of the liquid phase. + * @param[in] vapourComposition Composition of the vapor phase. + * @param[out] vapourFractionDerivs Derivatives of vapor fraction with respect to pressure, temperature, and composition. + * @param[out] liquidCompositionDerivs Derivatives of liquid phase composition. + * @param[out] vapourCompositionDerivs Derivatives of vapor phase composition. */ template< integer USD1, integer USD2, integer USD3 > GEOS_HOST_DEVICE @@ -110,6 +144,40 @@ struct NegativeTwoPhaseFlash arraySlice2d< real64, USD3 > const & liquidCompositionDerivs, arraySlice2d< real64, USD3 > const & vapourCompositionDerivs ); + /** + * @brief Compute the residual vector for a two-phase flash calculation. + * + * @details This method evaluates the phase equilibrium condition by computing + * the residuals of fugacity balance between liquid and vapor phases for each component. + * It also includes a mass balance residual for the vapor phase mole fraction. + * The compositions are calculated using the Rachford-Rice formulation and normalized. + * + * The fugacity coefficients are computed for both phases using the specified equation of state. + * The residuals are defined as: + * R_i = x_i * \phi_i^L - y_i * \phi_i^V + * R_N = \sum_{i=1}^N (y_i - x_i) + * where \phi_i^L and \phi_i^V are fugacity coefficients in liquid and vapor phases. + * + * @tparam USD1 Unit Stride Dimension for k-values array. + * @tparam USD2 Unit Stride Dimension for composition arrays. + * @tparam USD3 Unit Stride Dimension for residual array. + * + * @param[in] numComps Number of components in the mixture. + * @param[in] pressure System pressure [Pa]. + * @param[in] temperature System temperature [K]. + * @param[in] composition Overall feed composition (mole fractions). + * @param[in] componentProperties Thermodynamic properties of components. + * @param[in] flashData Flash calculation context including EOS types. + * @param[in] kValues Equilibrium ratios (K-values) for each component. + * @param[in] vapourPhaseMoleFraction Mole fraction of the vapor phase. + * @param[out] liquidComposition Computed composition of the liquid phase. + * @param[out] vapourComposition Computed composition of the vapor phase. + * @param[out] logLiquidFugacity Log fugacity coefficients for the liquid phase. + * @param[out] logVapourFugacity Log fugacity coefficients for the vapor phase. + * @param[out] residual Residual vector containing fugacity and mass balance errors. + * + * @return L2 norm of the residual vector. + */ template< int USD1, int USD2, int USD3 > GEOS_HOST_DEVICE static real64 calculateResidual( integer const numComps, @@ -126,24 +194,61 @@ struct NegativeTwoPhaseFlash arraySlice1d< real64 > const & logVapourFugacity, arraySlice1d< real64, USD3 > const & residual ); + /** + * @brief Calculates the residual vector and Jacobian matrix for a two-phase flash system. + * + * @details This method computes the nonlinear residuals and Jacobian matrix for a negative two-phase flash + * system using fugacity equilibrium and mass balance constraints. It is used in Newton-Raphson iterations + * to refine the solution of the flash problem. The primary variables in the Jacobian are the logarithm of + * the K-values (log(K)) and the vapor phase mole fraction. The Jacobian is constructed with respect to these + * variables. Missing components (i.e., those with zero mole fraction in the feed) are excluded from the + * fugacity and Jacobian calculations but are handled explicitly by setting diagonal Jacobian entries to unity. + * + * The method normalizes phase compositions, computes fugacity coefficients and their derivatives, and + * assembles the Jacobian matrix using chain rule and normalization sensitivities. + * + * @tparam USD1 Unit Stride Dimension for the K-values array. + * @tparam USD2 Unit Stride Dimension for the composition arrays. + * @tparam USD3 Unit Stride Dimension for the residual vector. + * @tparam USD4 Unit Stride Dimension for the Jacobian matrix. + * + * @param[in] numComps Number of components in the mixture. + * @param[in] pressure System pressure [Pa]. + * @param[in] temperature System temperature [K]. + * @param[in] composition Overall feed composition (mole fractions). + * @param[in] componentProperties Thermodynamic properties of each component. + * @param[in] flashData Flash calculation context including EOS types. + * @param[in] kValues Equilibrium ratios (K-values) for each component. + * @param[in] vapourPhaseMoleFraction Mole fraction of the vapor phase. + * @param[in] liquidComposition Composition of the liquid phase. + * @param[in] vapourComposition Composition of the vapor phase. + * @param[in] logLiquidFugacity Logarithm of fugacity coefficients in the liquid phase. + * @param[in] logVapourFugacity Logarithm of fugacity coefficients in the vapor phase. + * @param[in] logLiquidFugacityDerivs Derivatives of log fugacity in the liquid phase. + * @param[in] logVapourFugacityDerivs Derivatives of log fugacity in the vapor phase. + * @param[out] residual Residual vector containing fugacity and mass balance errors. + * @param[out] jacobian Jacobian matrix of the residuals with respect to log(K) and vapor fraction. + * + * @return Error norm of the residual vector. + */ template< int USD1, int USD2, int USD3, int USD4 > GEOS_HOST_DEVICE static real64 calculateResidualAndJacobian( integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - arraySlice1d< real64 const, USD1 > const & kValues, - real64 const & vapourPhaseMoleFraction, - arraySlice1d< real64, USD2 > const & liquidComposition, - arraySlice1d< real64, USD2 > const & vapourComposition, - arraySlice1d< real64 > const & logLiquidFugacity, - arraySlice1d< real64 > const & logVapourFugacity, - arraySlice2d< real64 > const & logLiquidFugacityDerivs, - arraySlice2d< real64 > const & logVapourFugacityDerivs, - arraySlice1d< real64, USD3 > const & residual, - arraySlice2d< real64, USD4 > const & jacobian ); + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + arraySlice1d< real64 const, USD1 > const & kValues, + real64 const & vapourPhaseMoleFraction, + arraySlice1d< real64, USD2 > const & liquidComposition, + arraySlice1d< real64, USD2 > const & vapourComposition, + arraySlice1d< real64 > const & logLiquidFugacity, + arraySlice1d< real64 > const & logVapourFugacity, + arraySlice2d< real64 > const & logLiquidFugacityDerivs, + arraySlice2d< real64 > const & logVapourFugacityDerivs, + arraySlice1d< real64, USD3 > const & residual, + arraySlice2d< real64, USD4 > const & jacobian ); private: /** @@ -173,19 +278,18 @@ struct NegativeTwoPhaseFlash */ template< integer USD1, integer USD2, integer USD3 > GEOS_HOST_DEVICE - static void computeDerivatives( - integer const numComps, - arraySlice1d< real64 const > const & totalComposition, - real64 const & phase1Fraction, - arraySlice1d< real64 const, USD1 > const & phase1Composition, - arraySlice1d< real64 const, USD1 > const & phase2Composition, - arraySlice1d< real64 const > const & phase1Fugacity, - arraySlice1d< real64 const > const & phase2Fugacity, - arraySlice2d< real64 const > const & phase1LogFugacityDerivs, - arraySlice2d< real64 const > const & phase2LogFugacityDerivs, - arraySlice1d< real64, USD2 > const & phase1FractionDerivs, - arraySlice2d< real64, USD3 > const & phase1CompositionDerivs, - arraySlice2d< real64, USD3 > const & phase2CompositionDerivs ); + static void computeDerivatives( integer const numComps, + arraySlice1d< real64 const > const & totalComposition, + real64 const & phase1Fraction, + arraySlice1d< real64 const, USD1 > const & phase1Composition, + arraySlice1d< real64 const, USD1 > const & phase2Composition, + arraySlice1d< real64 const > const & phase1Fugacity, + arraySlice1d< real64 const > const & phase2Fugacity, + arraySlice2d< real64 const > const & phase1LogFugacityDerivs, + arraySlice2d< real64 const > const & phase2LogFugacityDerivs, + arraySlice1d< real64, USD2 > const & phase1FractionDerivs, + arraySlice2d< real64, USD3 > const & phase1CompositionDerivs, + arraySlice2d< real64, USD3 > const & phase2CompositionDerivs ); /** * @brief A test for when the result of the negative flash should be truncated immediately diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index 5056eb972a6..5cca5ce92d4 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -49,8 +49,6 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, arraySlice1d< real64, USD2 > const & liquidComposition, arraySlice1d< real64, USD2 > const & vapourComposition ) { - GEOS_MARK_SCOPE(geos::constitutive::compositional::NegativeTwoPhaseFlash::compute); - constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; constexpr integer maxNumDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; @@ -73,7 +71,7 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, // Extract flash parameters integer const maxIterations = discreteFlashParameters[FlashParameters::FLASH_MAX_ITERATIONS]; real64 const flashTolerance = continuousFlashParameters[FlashParameters::FLASH_TOLERANCE]; - real64 const flashSSITolerance = LvArray::math::max( flashTolerance, continuousFlashParameters[FlashParameters::SSI_TOLERANCE] ); + real64 const flashSSITolerance = continuousFlashParameters[FlashParameters::SSI_TOLERANCE]; // Initialise compositions to feed composition for( integer ic = 0; ic < numComps; ++ic ) @@ -83,27 +81,27 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, } bool converged = false; - localIndex iterationCount = 0; + localIndex iterationCount = 0; // Start SSI iterations - for( ; ( !converged ) && (iterationCount < maxIterations); ++iterationCount ) + for(; ( !converged ) && (iterationCount < maxIterations); ++iterationCount ) { // Solve Rachford-Rice Equation vapourPhaseMoleFraction = RachfordRice::solve( kVapourLiquid.toSliceConst(), composition, presentComponents ); - real64 const error = calculateResidual( numComps, - pressure, - temperature, - composition, - componentProperties, - flashData, - kVapourLiquid.toSliceConst(), - vapourPhaseMoleFraction, - liquidComposition, - vapourComposition, - logLiquidFugacity, - logVapourFugacity, - residual ); + real64 const error = calculateResidual( numComps, + pressure, + temperature, + composition, + componentProperties, + flashData, + kVapourLiquid.toSliceConst(), + vapourPhaseMoleFraction, + liquidComposition, + vapourComposition, + logLiquidFugacity, + logVapourFugacity, + residual ); // Update K-values for( integer const ic : presentComponents ) @@ -114,54 +112,54 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, // Check convergence converged = ( error < flashTolerance ); - if (error < flashSSITolerance) + if( error < flashSSITolerance ) { break; } } // Start Newton iterations - StackArray< real64, 3, 2*maxNumComps * maxNumDofs > logFugacityDerivs( 2, numComps, numDofs ); - StackArray< real64, 2, (maxNumComps+1) * (maxNumComps+1) > jacobian( numComps+1, numComps+1 ); - arraySlice2d< real64 > const logLiquidFugacityDerivs = logFugacityDerivs[0]; - arraySlice2d< real64 > const logVapourFugacityDerivs = logFugacityDerivs[1]; + StackArray< real64, 3, 2*maxNumComps * maxNumDofs > logFugacityDerivs( 2, numComps, numDofs ); + StackArray< real64, 2, (maxNumComps+1) * (maxNumComps+1) > jacobian( numComps+1, numComps+1 ); + arraySlice2d< real64 > const logLiquidFugacityDerivs = logFugacityDerivs[0]; + arraySlice2d< real64 > const logVapourFugacityDerivs = logFugacityDerivs[1]; -for( ; ( !converged ) && (iterationCount < maxIterations); ++iterationCount ) + for(; ( !converged ) && (iterationCount < maxIterations); ++iterationCount ) { - real64 const error = calculateResidualAndJacobian( numComps, - pressure, - temperature, - composition, - componentProperties, - flashData, - kVapourLiquid.toSliceConst(), - vapourPhaseMoleFraction, - liquidComposition, - vapourComposition, - logLiquidFugacity, - logVapourFugacity, - logLiquidFugacityDerivs, - logVapourFugacityDerivs, - residual, - jacobian.toSlice() ); + real64 const error = calculateResidualAndJacobian( numComps, + pressure, + temperature, + composition, + componentProperties, + flashData, + kVapourLiquid.toSliceConst(), + vapourPhaseMoleFraction, + liquidComposition, + vapourComposition, + logLiquidFugacity, + logVapourFugacity, + logLiquidFugacityDerivs, + logVapourFugacityDerivs, + residual, + jacobian.toSlice() ); // Account for missing components in Jacobian - for( integer const ic : absentComponents ) - { - jacobian(ic, ic) = 1.0; - } - - // Solve for next step - solveLinearSystem( jacobian.toSlice(), residual ); - // Update K-values + for( integer const ic : absentComponents ) + { + jacobian( ic, ic ) = 1.0; + } + + // Solve for next step + solveLinearSystem( jacobian.toSlice(), residual ); + // Update K-values for( integer const ic : presentComponents ) { kVapourLiquid[ic] *= exp( -residual[ic] ); - } - vapourPhaseMoleFraction -= residual[numComps]; - // Check convergence - converged = ( error < flashTolerance ); } + vapourPhaseMoleFraction -= residual[numComps]; + // Check convergence + converged = ( error < flashTolerance ); + } // Test if we have converged to a null or trivial solution bool const testNegativeFlash = truncateCompositions( numComps, @@ -184,19 +182,18 @@ for( ; ( !converged ) && (iterationCount < maxIterations); ++iterationCount ) template< integer USD1, integer USD2, integer USD3 > GEOS_HOST_DEVICE -void NegativeTwoPhaseFlash::computeDerivatives( - integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - real64 const & vapourFraction, - arraySlice1d< real64 const, USD1 > const & liquidComposition, - arraySlice1d< real64 const, USD1 > const & vapourComposition, - arraySlice1d< real64, USD2 > const & vapourFractionDerivs, - arraySlice2d< real64, USD3 > const & liquidCompositionDerivs, - arraySlice2d< real64, USD3 > const & vapourCompositionDerivs ) +void NegativeTwoPhaseFlash::computeDerivatives( integer const numComps, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + real64 const & vapourFraction, + arraySlice1d< real64 const, USD1 > const & liquidComposition, + arraySlice1d< real64 const, USD1 > const & vapourComposition, + arraySlice1d< real64, USD2 > const & vapourFractionDerivs, + arraySlice2d< real64, USD3 > const & liquidCompositionDerivs, + arraySlice2d< real64, USD3 > const & vapourCompositionDerivs ) { constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; constexpr integer maxNumDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; @@ -357,23 +354,23 @@ real64 NegativeTwoPhaseFlash::calculateResidual( integer const numComps, template< int USD1, int USD2, int USD3, int USD4 > GEOS_HOST_DEVICE real64 NegativeTwoPhaseFlash::calculateResidualAndJacobian( integer const numComps, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const > const & composition, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - arraySlice1d< real64 const, USD1 > const & kValues, - real64 const & vapourPhaseMoleFraction, - arraySlice1d< real64, USD2 > const & liquidComposition, - arraySlice1d< real64, USD2 > const & vapourComposition, - arraySlice1d< real64 > const & logLiquidFugacity, - arraySlice1d< real64 > const & logVapourFugacity, - arraySlice2d< real64 > const & logLiquidFugacityDerivs, - arraySlice2d< real64 > const & logVapourFugacityDerivs, - arraySlice1d< real64, USD3 > const & residual, - arraySlice2d< real64, USD4 > const & jacobian ) + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + FlashData const & flashData, + arraySlice1d< real64 const, USD1 > const & kValues, + real64 const & vapourPhaseMoleFraction, + arraySlice1d< real64, USD2 > const & liquidComposition, + arraySlice1d< real64, USD2 > const & vapourComposition, + arraySlice1d< real64 > const & logLiquidFugacity, + arraySlice1d< real64 > const & logVapourFugacity, + arraySlice2d< real64 > const & logLiquidFugacityDerivs, + arraySlice2d< real64 > const & logVapourFugacityDerivs, + arraySlice1d< real64, USD3 > const & residual, + arraySlice2d< real64, USD4 > const & jacobian ) { - real64 const & V = vapourPhaseMoleFraction; + real64 const & V = vapourPhaseMoleFraction; // Calculate phase compositions --- for( integer ic = 0; ic < numComps; ++ic ) @@ -525,19 +522,18 @@ real64 NegativeTwoPhaseFlash::calculateResidualAndJacobian( integer const numCom template< integer USD1, integer USD2, integer USD3 > GEOS_HOST_DEVICE -void NegativeTwoPhaseFlash::computeDerivatives( - integer const numComps, - arraySlice1d< real64 const > const & totalComposition, - real64 const & phase1Fraction, - arraySlice1d< real64 const, USD1 > const & phase1Composition, - arraySlice1d< real64 const, USD1 > const & phase2Composition, - arraySlice1d< real64 const > const & phase1Fugacity, - arraySlice1d< real64 const > const & phase2Fugacity, - arraySlice2d< real64 const > const & phase1LogFugacityDerivs, - arraySlice2d< real64 const > const & phase2LogFugacityDerivs, - arraySlice1d< real64, USD2 > const & phase1FractionDerivs, - arraySlice2d< real64, USD3 > const & phase1CompositionDerivs, - arraySlice2d< real64, USD3 > const & phase2CompositionDerivs ) +void NegativeTwoPhaseFlash::computeDerivatives( integer const numComps, + arraySlice1d< real64 const > const & totalComposition, + real64 const & phase1Fraction, + arraySlice1d< real64 const, USD1 > const & phase1Composition, + arraySlice1d< real64 const, USD1 > const & phase2Composition, + arraySlice1d< real64 const > const & phase1Fugacity, + arraySlice1d< real64 const > const & phase2Fugacity, + arraySlice2d< real64 const > const & phase1LogFugacityDerivs, + arraySlice2d< real64 const > const & phase2LogFugacityDerivs, + arraySlice1d< real64, USD2 > const & phase1FractionDerivs, + arraySlice2d< real64, USD3 > const & phase1CompositionDerivs, + arraySlice2d< real64, USD3 > const & phase2CompositionDerivs ) { constexpr integer maxNumDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; constexpr integer maxNumVals = MultiFluidConstants::MAX_NUM_COMPONENTS+1; @@ -672,46 +668,6 @@ bool NegativeTwoPhaseFlash::truncateCompositions( integer const numComps, return (V < MultiFluidConstants::epsilon|| L < MultiFluidConstants::epsilon); } -// Assume calculateFugacity is defined elsewhere. -// This function calculates the log fugacities and their derivatives for a given phase. -template< int USD > -void calculateFugacity( int const numComps, - double const pressure, - double const temperature, - ComponentProperties::KernelWrapper const & componentProperties, - FlashData const & flashData, - EquationOfStateType const equationOfState, - std::vector< double > const & phaseComposition, - std::vector< double > & logFugacity, - std::vector< std::vector< double > > & logFugacityDerivatives ) -{ - StackArray< real64, 2, 2*9 > workSpace( 2, numComps ); - arraySlice1d< real64, USD > phaseCompositionSlice = workSpace[0]; - arraySlice1d< real64, USD > logFugacitySlice = workSpace[1]; - StackArray< real64, 2, 9*11 > derivatives( numComps, numComps+2 ); - for( integer ic = 0; ic < numComps; ++ic ) - { - phaseCompositionSlice[ic] = phaseComposition[ic]; - } - FugacityCalculator::computeLogFugacityDerivatives( numComps, - pressure, - temperature, - phaseCompositionSlice.toSliceConst(), - componentProperties, - equationOfState, - flashData, - logFugacitySlice, - derivatives.toSlice() ); - for( integer ic = 0; ic < numComps; ++ic ) - { - logFugacity[ic] = logFugacitySlice[ic]; - for( integer jc = 0; jc < numComps; ++jc ) - { - logFugacityDerivatives[ic][jc] = derivatives( ic, 2 + jc ); - } - } -} - } // namespace compositional } // namespace constitutive } // namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp index 051353fbb82..8fef4857509 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp @@ -38,29 +38,70 @@ namespace constitutive namespace compositional { +/** + * @struct StabilityTest + * @brief Performs stability analysis for a reservoir fluid. + * + * This class implements a stability test to determine if a single-phase fluid mixture is thermodynamically + * stable or if it will split into multiple phases. The algorithm follows the tangent-plane-distance (TPD) + * method, as described in the reference by Michelsen (1982). + * + * The method involves finding a trial composition ($y_i$) that minimizes the tangent-plane-distance ($TPD$) + * at a given pressure and temperature. The TPD for a trial phase with composition $y$ relative to a sample + * phase with composition $z$ is given by: + * $$ TPD(y) = \sum_{i=1}^{nc} y_i \left[ \ln(y_i) - \ln(z_i) + \ln(\phi}_i(y)) - \ln(\phi_i(z)) \right] $$ + * where $nc$ is the number of components, $z_i$ and $y_i$ are the mole fractions of component $i$ in + * the sample and trial phases, respectively, and $\phi_i$ and $\hat{\phi}_i$ are the fugacity coefficients + * of component $i$ in the sample and trial phases, respectively. + * + * The stability analysis is performed by solving for the stationary points of the TPD function. The solution + * is found by a combination of successive substitution iterations (SSI) and Newton-Raphson iterations. + * SSI is used initially to provide a good starting point for the faster, but more sensitive, Newton-Raphson + * method. The mixture is considered unstable if the minimum TPD is less than zero, indicating that a more + * stable phase exists. + * + * Reference: Michelsen, M.L. (1982). The Isothermal Flash Problem. Part I. Stability. + * Fluid Phase Equilibria, 9(1), 1–19. https://doi.org/10.1016/0378-3812(82)85001-2 + */ struct StabilityTest { private: static constexpr integer maxNumComps = MultiFluidConstants::MAX_NUM_COMPONENTS; + static constexpr integer maxNumDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; using Deriv = constitutive::multifluid::DerivativeOffset; + public: /** - * @brief Perform a two-phase stability test - * @param[in] numComps number of components - * @param[in] pressure pressure - * @param[in] temperature temperature - * @param[in] composition composition of the mixture - * @param[in] componentProperties The compositional component properties - * @param[in] flashData The parameters required for the flash - * @param[in] kValues the k-values to use to create test samples - * @param[in] continuousFlashParameters List of continuous (float) parameters for flash - * @param[in] discreteFlashParameters List of discrete (integer) parameters for flash - * @param[out] unstableMixture The stability test result indicating if the mixture is unstable - * @param[out] incipientEquationOfState The equation of state of the incipient phase - * @param[out] incipientComposition The composition of the incipient phase. This will be - * set to the incipient phase composition at the stationary point that is furthest - * from the trivial solution. - * @return a flag indicating that the stability test is successful i.e. mixture is unstable or all test points converged + * @brief Perform a two-phase stability test using the Tangent Plane Distance (TPD) method. + * + * The stability analysis is performed by solving for the stationary points of the TPD function. The solution + * is found by a combination of successive substitution iterations (SSI) and Newton-Raphson iterations. + * SSI is used initially to provide a good starting point for the faster, but more sensitive, Newton-Raphson + * method. The mixture is considered unstable if the minimum TPD is less than zero, indicating that a more + * stable phase exists. + * + * This implementation supports asymmetric equations of state, where the EOS used for the + * incipient phase may differ from that of the original mixture. This is handled by testing + * both configurations independently. + * + * @tparam USD1 Unit Stride Dimension for the composition array. + * @tparam USD2 Unit Stride Dimension for the K-values array. + * + * @param[in] numComps Number of components in the mixture. + * @param[in] pressure Pressure of the system [Pa]. + * @param[in] temperature Temperature of the system [K]. + * @param[in] composition Mole fractions of each component in the mixture (must be normalized). + * @param[in] componentProperties Thermodynamic properties of each component. + * @param[in] flashData Flash calculation context, including EOS types for liquid and vapor phases. + * @param[in] kValues Initial equilibrium ratios (K-values) used to generate trial compositions. + * @param[in] continuousFlashParameters Continuous parameters (e.g., tolerances, thresholds) for the flash calculation. + * @param[in] discreteFlashParameters Discrete parameters (e.g., max iterations) for the flash calculation. + * @param[out] unstableMixture Flag indicating whether the mixture is unstable. + * @param[out] incipientEquationOfState EOS type of the incipient phase (liquid or vapor). + * @param[out] incipientComposition Composition of the incipient phase at the stationary point furthest from the trivial solution. + * + * @return True if the mixture is unstable or all trial compositions converge to stationary points; false otherwise. + * */ template< integer USD1, integer USD2 > GEOS_HOST_DEVICE @@ -78,18 +119,31 @@ struct StabilityTest arraySlice1d< real64 > const & incipientComposition ); /** - * @brief Compute derivatives of the incipient phase composition - * @param[in] numComps number of components - * @param[in] pressure pressure - * @param[in] temperature temperature - * @param[in] composition composition of the mixture - * @param[in] componentProperties The compositional component properties - * @param[in] sampleEquationOfState The equation of state for the sample - * @param[in] sampleEquationOfState The equation of state for the incipient phase - * @param[in] flashData The parameters required for the flash - * @param[in] incipientComposition The composition of the incipient phase - * @param[out] incipientCompositionDerivs Derivatives of the composition of the incipient phase - * @param[out] compositionDerivs Workspace + * @brief Compute derivatives of the incipient phase composition with respect to pressure, temperature, and overall composition. + * + * @details This method calculates the sensitivity of the incipient phase composition resulting from a phase stability test. + * It computes the partial derivatives of the incipient composition with respect to pressure, temperature, and each component + * of the overall mixture composition. + * + * The implementation solves a linear system derived from the stationarity condition of the Tangent Plane Distance (TPD) + * function. It uses fugacity derivatives from both the sample and incipient phases, and enforces the constraint that the + * incipient composition must sum to unity. + * + * @tparam USD1 Unit Stride Dimension for the composition array. + * @tparam USD2 Unit Stride Dimension for the derivative arrays. + * + * @param[in] numComps Number of components in the mixture. + * @param[in] pressure Pressure of the system [Pa]. + * @param[in] temperature Temperature of the system [K]. + * @param[in] composition Mole fractions of each component in the original mixture. + * @param[in] componentProperties Thermodynamic properties of each component. + * @param[in] sampleEquationOfState EOS used for the original mixture. + * @param[in] incipientEquationOfState EOS used for the incipient phase. + * @param[in] flashData Flash calculation context and EOS configuration. + * @param[in] incipientComposition Composition of the incipient phase. + * @param[out] incipientCompositionDerivs Derivatives of the incipient composition with respect to pressure, temperature, and composition. + * @param[out] compositionDerivs Workspace for storing derivatives of the sample composition. + * */ template< integer USD1, integer USD2 > GEOS_HOST_DEVICE @@ -103,87 +157,40 @@ struct StabilityTest FlashData const & flashData, arraySlice1d< real64 const > const & incipientComposition, arraySlice2d< real64, USD2 > const & incipientCompositionDerivs, - arraySlice2d< real64, USD2 > const & compositionDerivs ) - { - integer constexpr maxNumRows = MultiFluidConstants::MAX_NUM_COMPONENTS + 1; - integer constexpr maxDofs = MultiFluidConstants::MAX_NUM_COMPONENTS + 2; - - integer const numDofs = 2 + numComps; - - StackArray< real64, 1, maxNumComps > logFugacity( numComps ); - auto const & logFugacityIncipientDerivs = incipientCompositionDerivs; - auto const & logFugacitySampleDerivs = compositionDerivs; - - FugacityCalculator::computeLogFugacityDerivatives( numComps, - pressure, - temperature, - composition, - componentProperties, - sampleEquationOfState, - flashData, - logFugacity.toSlice(), - logFugacitySampleDerivs ); - FugacityCalculator::computeLogFugacityDerivatives( numComps, - pressure, - temperature, - incipientComposition, - componentProperties, - incipientEquationOfState, - flashData, - logFugacity.toSlice(), - logFugacityIncipientDerivs ); - - StackArray< real64, 2, maxNumRows * maxNumRows, MatrixLayout::COL_MAJOR_PERM > A( numComps + 1, numComps + 1 ); - StackArray< real64, 2, maxNumRows * maxDofs, MatrixLayout::COL_MAJOR_PERM > X( numComps + 1, numDofs ); - - for( integer ic = 0; ic < numComps; ++ic ) - { - real64 const yi = incipientComposition[ic]; - for( integer jc = 0; jc < numComps; ++jc ) - { - real64 const df_dyj = logFugacityIncipientDerivs( ic, Deriv::dC+jc ); - A( ic, jc ) = yi*df_dyj; - } - A( ic, ic ) += 1.0; - A( ic, numComps ) = yi; - A( numComps, ic ) = 1.0; - } - A( numComps, numComps ) = 0.0; - - for( integer ic = 0; ic < numComps; ++ic ) - { - real64 const yi = incipientComposition[ic]; - for( integer const idof : {Deriv::dP, Deriv::dT} ) - { - X( ic, idof ) = yi*(-logFugacityIncipientDerivs( ic, idof ) + logFugacitySampleDerivs( ic, idof )); - } - for( integer jc = 0; jc < numComps; ++jc ) - { - integer const idof = Deriv::dC + jc; - X( ic, idof ) = yi*logFugacitySampleDerivs( ic, idof ); - } - if( MultiFluidConstants::epsilon < composition[ic] ) - { - X( ic, Deriv::dC+ic ) += yi/composition[ic]; - } - } - for( integer idof = 0; idof < numDofs; ++idof ) - { - X( numComps, idof ) = 0.0; - } - - // Solve linear system - solveLinearSystem( A.toSlice(), X.toSlice() ); - - for( integer idof = 0; idof < numDofs; ++idof ) - { - for( integer ic = 0; ic < numComps; ++ic ) - { - incipientCompositionDerivs( ic, idof ) = X( ic, idof ); - } - } - } + arraySlice2d< real64, USD2 > const & compositionDerivs ); + /** + * @brief Calculates the residual vector and Tangent Plane Distance (TPD) for a trial composition. + * + * @details This method evaluates the deviation of a trial composition from stationarity + * in the context of phase stability analysis. It computes the residual vector used in + * iterative solvers (SSI/Newton) and the tangent plane distance (TPD) which indicates + * whether the trial composition has lower Gibbs energy than the original mixture. + * + * The trial composition is provided in logarithmic form and exponentiated internally. + * Missing components (not present in presentComponents) are ignored in the residual + * and TPD calculation. The composition is normalized after exponentiation. + * + * @tparam USD1 Unit Stride Dimension for logTestComposition array. + * @tparam USD2 Unit Stride Dimension for testComposition array. + * @tparam USD3 Unit Stride Dimension for residual array. + * + * @param[in] numComps Number of components in the mixture. + * @param[in] presentComponents Indices of components present in the mixture. + * @param[in] pressure System pressure [Pa]. + * @param[in] temperature System temperature [K]. + * @param[in] componentProperties Thermodynamic properties of each component. + * @param[in] equationOfState Equation of state used for fugacity calculations. + * @param[in] flashData Flash calculation context. + * @param[in] logTestComposition Logarithm of trial composition. + * @param[out] tangentPlaneDistance Computed tangent plane distance (TPD). + * @param[out] testComposition Trial composition (exponentiated and normalized). + * @param[out] testLogFugacity Log fugacity coefficients of the trial composition. + * @param[out] residual Residual vector for iterative solver. + * + * @return Error norm of the residual vector. + * + */ template< int USD1, int USD2, int USD3 > GEOS_HOST_DEVICE static real64 calculateResidual( integer const numComps, @@ -199,6 +206,36 @@ struct StabilityTest arraySlice1d< real64 > const & testLogFugacity, arraySlice1d< real64, USD3 > const & residual ); + /** + * @brief Calculates the residual vector and Jacobian matrix for a trial composition in phase stability analysis. + * + * @details This method evaluates the stationarity of a trial composition using the Tangent Plane Distance (TPD) criterion. + * It computes the residual vector and the Jacobian matrix required for Newton-Raphson iterations. + * The fugacity and its derivatives are calculated using the specified equation of state. + * Missing components (not present in the trial composition) are ignored in the residual and Jacobian calculations. + * + * @tparam USD1 Unit Stride Dimension for logTestComposition array. + * @tparam USD2 Unit Stride Dimension for testComposition array. + * @tparam USD3 Unit Stride Dimension for residual array. + * @tparam USD4 Unit Stride Dimension for jacobian array. + * + * @param[in] numComps Number of components in the mixture. + * @param[in] presentComponents Indices of components present in the trial composition. + * @param[in] pressure Pressure of the system [Pa]. + * @param[in] temperature Temperature of the system [K]. + * @param[in] componentProperties Thermodynamic properties of each component. + * @param[in] equationOfState Equation of state used for fugacity calculations. + * @param[in] flashData Flash calculation context and parameters. + * @param[in] logTestComposition Logarithm of the trial composition. + * @param[out] tangentPlaneDistance Computed TPD value for the trial composition. + * @param[out] testComposition Normalized trial composition. + * @param[out] testFugacity Log fugacity coefficients of the trial composition. + * @param[out] logTestFugacityDerivs Derivatives of log fugacity with respect to composition. + * @param[out] residual Residual vector used in Newton-Raphson iterations. + * @param[out] jacobian Jacobian matrix of the residual vector. + * + * @return Error norm of the residual vector. + */ template< int USD1, int USD2, int USD3, int USD4 > GEOS_HOST_DEVICE static real64 calculateResidualAndJacobian( integer const numComps, diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp index 8ebbf0dd3c1..d95f0ba17aa 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp @@ -46,14 +46,11 @@ bool StabilityTest::compute( integer const numComps, EquationOfStateType & incipientEquationOfState, arraySlice1d< real64 > const & incipientComposition ) { - GEOS_MARK_SCOPE(geos::constitutive::compositional::StabilityTest::compute); - - integer constexpr maxDofs = maxNumComps + 2; integer const numDofs = 2 + numComps; stackArray2d< real64, 5*maxNumComps > workSpace( 5, numComps ); stackArray2d< real64, maxNumComps *maxNumComps > jacobian( numComps, numComps ); - stackArray2d< real64, maxNumComps *maxDofs > derivatives( numComps, numDofs ); + stackArray2d< real64, maxNumComps *maxNumDofs > derivatives( numComps, numDofs ); arraySlice1d< real64 > logFugacity = workSpace[0]; arraySlice1d< real64 > logTestComposition = workSpace[1]; arraySlice1d< real64 > testComposition = workSpace[2]; @@ -137,7 +134,7 @@ bool StabilityTest::compute( integer const numComps, localIndex iterationCount = 0; // Start with SSI iterations - for( ; ((!converged) && (iterationCount < maxIterations)); ++iterationCount ) + for(; (!converged) && (iterationCount < maxIterations); ++iterationCount ) { for( integer const ic : presentComponents ) { @@ -170,7 +167,7 @@ bool StabilityTest::compute( integer const numComps, } // Start with Newton iterations - for(; ((!converged) && (iterationCount < maxIterations)); ++iterationCount ) + for(; (!converged) && (iterationCount < maxIterations); ++iterationCount ) { for( integer const ic : presentComponents ) { @@ -192,7 +189,7 @@ bool StabilityTest::compute( integer const numComps, jacobian.toSlice() ); for( integer const ic : absentComponents ) { - jacobian(ic, ic) = 1.0; + jacobian( ic, ic ) = 1.0; } solveLinearSystem( jacobian.toSlice(), residual ); // Update to next step @@ -204,7 +201,7 @@ bool StabilityTest::compute( integer const numComps, // Check stationarity converged = ( error < stabilityTolerance ); } - + allConverged = allConverged && converged; // Calculate the tangent-plane-distance (TPD) and distance to the trivial solution @@ -249,6 +246,98 @@ bool StabilityTest::compute( integer const numComps, return unstableMixture || allConverged; } +template< integer USD1, integer USD2 > +GEOS_HOST_DEVICE +void StabilityTest::computeDerivatives( integer const numComps, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, USD1 > const & composition, + ComponentProperties::KernelWrapper const & componentProperties, + EquationOfStateType const & sampleEquationOfState, + EquationOfStateType const & incipientEquationOfState, + FlashData const & flashData, + arraySlice1d< real64 const > const & incipientComposition, + arraySlice2d< real64, USD2 > const & incipientCompositionDerivs, + arraySlice2d< real64, USD2 > const & compositionDerivs ) +{ + integer constexpr maxNumRows = MultiFluidConstants::MAX_NUM_COMPONENTS + 1; + + integer const numDofs = 2 + numComps; + + StackArray< real64, 1, maxNumComps > logFugacity( numComps ); + auto const & logFugacityIncipientDerivs = incipientCompositionDerivs; + auto const & logFugacitySampleDerivs = compositionDerivs; + + FugacityCalculator::computeLogFugacityDerivatives( numComps, + pressure, + temperature, + composition, + componentProperties, + sampleEquationOfState, + flashData, + logFugacity.toSlice(), + logFugacitySampleDerivs ); + FugacityCalculator::computeLogFugacityDerivatives( numComps, + pressure, + temperature, + incipientComposition, + componentProperties, + incipientEquationOfState, + flashData, + logFugacity.toSlice(), + logFugacityIncipientDerivs ); + + StackArray< real64, 2, maxNumRows * maxNumRows, MatrixLayout::COL_MAJOR_PERM > A( numComps + 1, numComps + 1 ); + StackArray< real64, 2, maxNumRows * maxNumDofs, MatrixLayout::COL_MAJOR_PERM > X( numComps + 1, numDofs ); + + for( integer ic = 0; ic < numComps; ++ic ) + { + real64 const yi = incipientComposition[ic]; + for( integer jc = 0; jc < numComps; ++jc ) + { + real64 const df_dyj = logFugacityIncipientDerivs( ic, Deriv::dC+jc ); + A( ic, jc ) = yi*df_dyj; + } + A( ic, ic ) += 1.0; + A( ic, numComps ) = yi; + A( numComps, ic ) = 1.0; + } + A( numComps, numComps ) = 0.0; + + for( integer ic = 0; ic < numComps; ++ic ) + { + real64 const yi = incipientComposition[ic]; + for( integer const idof : {Deriv::dP, Deriv::dT} ) + { + X( ic, idof ) = yi*(-logFugacityIncipientDerivs( ic, idof ) + logFugacitySampleDerivs( ic, idof )); + } + for( integer jc = 0; jc < numComps; ++jc ) + { + integer const idof = Deriv::dC + jc; + X( ic, idof ) = yi*logFugacitySampleDerivs( ic, idof ); + } + if( MultiFluidConstants::epsilon < composition[ic] ) + { + X( ic, Deriv::dC+ic ) += yi/composition[ic]; + } + } + for( integer idof = 0; idof < numDofs; ++idof ) + { + X( numComps, idof ) = 0.0; + } + + // Solve linear system + solveLinearSystem( A.toSlice(), X.toSlice() ); + + for( integer idof = 0; idof < numDofs; ++idof ) + { + for( integer ic = 0; ic < numComps; ++ic ) + { + incipientCompositionDerivs( ic, idof ) = X( ic, idof ); + } + } +} + template< int USD1, int USD2, int USD3 > GEOS_HOST_DEVICE real64 StabilityTest::calculateResidual( integer const numComps, diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp index 7e915bd0fa0..de4ba556350 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/models/NegativeTwoPhaseFlashModel.hpp @@ -150,10 +150,6 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate if( unstableMixture || !stabilityStatus ) { // Unstable mixture -std::ostringstream os; -os << "INCIPIENT " -<< std::scientific << incipientComposition.toSlice() << " " -<< std::scientific << kVapourLiquid.toSliceConst() << " "; // Iterative solve to converge flash bool const flashStatus = NegativeTwoPhaseFlash::compute( m_numComponents, pressure, @@ -167,11 +163,10 @@ os << "INCIPIENT " phaseFraction.value[m_vapourIndex], phaseCompFraction.value[m_liquidIndex], phaseCompFraction.value[m_vapourIndex] ); -os << "V " << phaseFraction.value[m_vapourIndex] << " " << kVapourLiquid.toSliceConst() << " "; GEOS_ERROR_IF( !flashStatus, - GEOS_FMT( "Negative two phase flash failed to converge at pressure {:.7e}, temperature {:.8f} and composition ", - pressure, temperature ) << compFraction << " KV " << os.str() ); + GEOS_FMT( "Negative two phase flash failed to converge at pressure {:.7e}, temperature {:.8f}, composition ", + pressure, temperature ) << compFraction << " and k-values " << kValues[0] ); // Calculate derivatives NegativeTwoPhaseFlash::computeDerivatives( m_numComponents, diff --git a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp index a32cb1b8cf3..2f2698d28fc 100644 --- a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp +++ b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp @@ -108,24 +108,25 @@ void testNumericalDerivative( real64 const x, selectedDerivative = deriv; } } - //checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, - // GEOS_FMT( "Numerical derivative for component {}", i ) ); - ((void)relTolerance); - ((void)absTolerance); - real64 const maxV = 1.0e-14 + LvArray::math::max( LvArray::math::abs( selectedDerivative ), LvArray::math::abs( derivatives[i] )); - std::cout - << std::setw( 2 ) << i << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << selectedDerivative << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << derivatives[i] << " | " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << leftValues[i] << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << centreValues[i] << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << rightValues[i] << " | " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << selectedDerivative - derivatives[i] << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << (selectedDerivative - derivatives[i])/maxV << " " - << "\n"; + checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, + GEOS_FMT( "Numerical derivative for component {}", i ) ); + /* + ((void)relTolerance); + ((void)absTolerance); + real64 const maxV = 1.0e-14 + LvArray::math::max( LvArray::math::abs( selectedDerivative ), LvArray::math::abs( derivatives[i] )); + std::cout + << std::setw( 2 ) << i << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << selectedDerivative << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << derivatives[i] << " | " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << leftValues[i] << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << centreValues[i] << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << rightValues[i] << " | " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << selectedDerivative - derivatives[i] << " " + << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << (selectedDerivative - derivatives[i])/maxV << " " + << "\n"; + } + std::cout << "----------------------------------------------------------\n";*/ } - std::cout << "----------------------------------------------------------\n"; -} /** * @brief Tests a multi-valued function against a second derivative @@ -142,53 +143,53 @@ void testNumericalDerivative( real64 const x, * @param absTolerance The absolute tolerance to use for the comparison * @param relTolerance The relative tolerance to use for the comparison */ -template< integer numValues, typename FUNCTION > -void testNumericalSecondDerivative( real64 const x, - real64 const dx, - arraySlice1d< real64 const > const & derivatives, - FUNCTION && function, - real64 const absTolerance = absTol, - real64 const relTolerance = relTol ) -{ - stackArray2d< real64, 5*numValues > values( 5, numValues ); - function( x-2.0*dx, values[0] ); - function( x-dx, values[1] ); - function( x, values[2] ); - function( x+dx, values[3] ); - function( x+2.0*dx, values[4] ); - - real64 constexpr stencils[6][5] = { - {1.0, -2.0, 1.0, 0.0, 0.0}, - {-1.0, 4.0, -5.0, 2.0, 0.0}, - {-1.0/12.0, 16.0/12.0, -30.0/12.0, 16.0/12.0, -1.0/12.0}, - {0.0, 1.0, -2.0, 1.0, 0.0}, - {0.0, -1.0, 4.0, -5.0, 2.0}, - {0.0, 0.0, 1.0, -2.0, 1.0}, - }; - real64 const invdx2 = 1.0 / (dx*dx); - for( integer i = 0; i < numValues; ++i ) + template< integer numValues, typename FUNCTION > + void testNumericalSecondDerivative( real64 const x, + real64 const dx, + arraySlice1d< real64 const > const & derivatives, + FUNCTION && function, + real64 const absTolerance = absTol, + real64 const relTolerance = relTol ) { - real64 minError = LvArray::NumericLimits< real64 >::max; - real64 selectedDerivative = 0.0; - for( integer si = 0; si < 6; si++ ) + stackArray2d< real64, 5*numValues > values( 5, numValues ); + function( x-2.0*dx, values[0] ); + function( x-dx, values[1] ); + function( x, values[2] ); + function( x+dx, values[3] ); + function( x+2.0*dx, values[4] ); + + real64 constexpr stencils[6][5] = { + {1.0, -2.0, 1.0, 0.0, 0.0}, + {-1.0, 4.0, -5.0, 2.0, 0.0}, + {-1.0/12.0, 16.0/12.0, -30.0/12.0, 16.0/12.0, -1.0/12.0}, + {0.0, 1.0, -2.0, 1.0, 0.0}, + {0.0, -1.0, 4.0, -5.0, 2.0}, + {0.0, 0.0, 1.0, -2.0, 1.0}, + }; + real64 const invdx2 = 1.0 / (dx*dx); + for( integer i = 0; i < numValues; ++i ) { - real64 deriv = 0.0; - for( integer ci = 0; ci < 5; ci++ ) + real64 minError = LvArray::NumericLimits< real64 >::max; + real64 selectedDerivative = 0.0; + for( integer si = 0; si < 6; si++ ) { - deriv += stencils[si][ci]*values( ci, i ); - } - deriv *= invdx2; - real64 const error = LvArray::math::abs( deriv - derivatives[i] ); - if( error < minError ) - { - minError = error; - selectedDerivative = deriv; + real64 deriv = 0.0; + for( integer ci = 0; ci < 5; ci++ ) + { + deriv += stencils[si][ci]*values( ci, i ); + } + deriv *= invdx2; + real64 const error = LvArray::math::abs( deriv - derivatives[i] ); + if( error < minError ) + { + minError = error; + selectedDerivative = deriv; + } } + checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, + GEOS_FMT( "Numerical derivative for component {}", i ) ); } - checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, - GEOS_FMT( "Numerical derivative for component {}", i ) ); } -} }// namespace internal diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp index 3c9336ac235..04bc00fcbbe 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashModel.cpp @@ -67,38 +67,13 @@ struct FluidData< 4 > static constexpr integer testComponents[numTestComps] = {0, 1, 3}; static std::unique_ptr< TestFluid< 4 > > createFluid() { - auto fluid = TestFluid< 4 >::create( {Fluid::CH4, Fluid::CO2, Fluid::N2, Fluid::H2O} ); - const std::array< real64 const, 6 > bics = { 0.0, 0.0, 0.0, 0.4850, 0.1896, 0.4778 }; + auto fluid = TestFluid< 4 >::create( {Fluid::CH4, Fluid::CO2, Fluid::H2S, Fluid::H2O} ); + const std::array< real64 const, 6 > bics = { 0.0, 0.0, 0.0, 0.4850, 0.1896, 0.1353 }; fluid->setBinaryCoefficients( bics ); return fluid; } }; - /* - -*/ - template<> struct FluidData< 9 > { @@ -156,7 +131,7 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< flashParameters->m_continuousParameters[FlashParameters::STABILITY_TOLERANCE] = 1.0e-12; flashParameters->m_continuousParameters[FlashParameters::STABILITY_THRESHOLD] = -1.0e-3; flashParameters->m_discreteParameters[FlashParameters::FLASH_MAX_ITERATIONS] = 20; - flashParameters->m_continuousParameters[FlashParameters::SSI_TOLERANCE] = 1.0e-3; + flashParameters->m_continuousParameters[FlashParameters::SSI_TOLERANCE] = 1.0e-12; m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::LIQUID)); m_phaseTypes.emplace_back( static_cast< integer >(PhaseType::VAPOUR)); @@ -179,9 +154,6 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< stackArray2d< real64, (numPhases-1)*numComps > kValues( numPhases-1, numComps ); LvArray::forValuesInSlice( kValues.toSlice(), []( real64 & v ){ v = 0.0; } ); - std::array kv{ 1.364671e+03, 1.595669e+02, 1.718535e+02, 6.450368e-02 }; - for (int i = 0; i < 4; i++) kValues(0,i) = kv[i]; - CompProp phaseFractionData( 1, 1, numPhases ); PhaseProp dPhaseFractionData( 1, 1, numPhases, numDofs ); PhaseProp phaseComponentFractionData( 1, 1, numPhases, numComps ); @@ -202,8 +174,7 @@ class NegativeTwoPhaseFlashModelTestFixture : public ::testing::TestWithParam< kValues.toSlice(), PhasePropSlice( phaseFraction, dPhaseFraction ), PhaseCompSlice( phaseComponentFraction, dPhaseComponentFraction ) ); -return; - + for( integer ip = 0; ip < numPhases; ip++ ) { checkRelativeError( phaseFraction[ip], expectedPhaseFraction[ip], relTol, absTol ); @@ -359,25 +330,23 @@ return; array1d< integer > m_phaseTypes{}; }; -//using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; -//using SoaveRedlichKwong2 = NegativeTwoPhaseFlashModelTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; +using PengRobinson9 = NegativeTwoPhaseFlashModelTestFixture< 9 >; +using SoaveRedlichKwong2 = NegativeTwoPhaseFlashModelTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; using SoreideWhitson4 = NegativeTwoPhaseFlashModelTestFixture< 4, EquationOfStateType::SoreideWhitson >; -//TEST_P( PengRobinson9, testFlash ) -//{ -// testFlash( GetParam() ); -//} -//TEST_P( SoaveRedlichKwong2, testFlash ) -//{ -// testFlash( GetParam() ); -//} +TEST_P( PengRobinson9, testFlash ) +{ + testFlash( GetParam() ); +} +TEST_P( SoaveRedlichKwong2, testFlash ) +{ + testFlash( GetParam() ); +} TEST_P( SoreideWhitson4, testFlash ) { testFlash( GetParam() ); } - /* - TEST_P( PengRobinson9, testFlashDerivatives ) { auto const param = GetParam(); @@ -402,7 +371,6 @@ TEST_P( SoreideWhitson4, testFlashDerivatives ) setStabilityThreshold( 1.0e-8 ); testFlashDerivatives( param ); } -*/ //------------------------------------------------------------------------------- // Data @@ -410,7 +378,6 @@ TEST_P( SoreideWhitson4, testFlashDerivatives ) /* UNCRUSTIFY-OFF */ -/* INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, PengRobinson9, ::testing::ValuesIn>({ @@ -422,36 +389,33 @@ INSTANTIATE_TEST_SUITE_P( {1.00000e+07, 293.15, { 0.13701652, 0.00320982, 0.10906380, 0.08659405, 0.09558042, 0.05469515, 0.02598050, 0.01902140, 0.46883834 }, 0.99999993, 0.00000007, { 0.13701653, 0.08659404, 0.46883837 }, { 0.00549895, 0.21806197, 0.00110727 }} }) ); -*/ INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoreideWhitson4, ::testing::ValuesIn>({ - //{2.01675e+07, 349.15, { 0.00000000, 0.00180029, 0.00073062, 0.99746900 }, 1.00000000, 0.00000000, { 0.00000000, 0.00180029, 0.99746900 }, { 0.00000000, 0.00180029, 0.99746900 }}, - //{1.07250e+07, 349.15, { 0.42400000, 0.05624000, 0.05624000, 0.46351000 }, 0.46391991, 0.53608009, { 0.00109926, 0.00153071, 0.99250187 }, { 0.78998321, 0.10358608, 0.00573284 }}, - //{1.06611e+07, 349.15, { 0.42341000, 0.05616000, 0.05616000, 0.46426000 }, 0.46465757, 0.53534243, { 0.00109380, 0.00152509, 0.99252663 }, { 0.78997286, 0.10358214, 0.00575264 }}, - //{1.92943e+07, 349.15, { 0.62210000, 0.08283000, 0.08283000, 0.21224000 }, 0.21083142, 0.78916858, { 0.00172629, 0.00206379, 0.99021290 }, { 0.78783679, 0.10440721, 0.00439958 }}, - //{2.00000e+07, 349.15, { 0.75000000, 0.10000000, 0.10000000, 0.05000000 }, 0.04630725, 0.95369275, { 0.00176884, 0.00209963, 0.99002996 }, { 0.78633091, 0.10475362, 0.00435616 }}, - //{1.99953e+07, 349.15, { 0.96334500, 0.01267200, 0.01266500, 0.01131700 }, 0.00782092, 0.99217908, { 0.00199275, 0.00025091, 0.99699415 }, { 0.97092389, 0.01276992, 0.00354735 }}, - //{1.99971e+07, 349.15, { 0.96329100, 0.01267200, 0.01266500, 0.01137300 }, 0.00787742, 0.99212258, { 0.00199287, 0.00025093, 0.99699395 }, { 0.97092271, 0.01277061, 0.00354719 }}, - //{1.00000e+07, 293.15, { 0.75000000, 0.05000000, 0.05000000, 0.15000000 }, 0.15072066, 0.84927934, { 0.00150781, 0.00166788, 0.99309883 }, { 0.88283407, 0.05857745, 0.00037619 }}, - //{1.00000e+07, 288.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.00144000, 0.00165800, 0.99682900 }}, - //{1.00000e+07, 293.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.00144000, 0.00165800, 0.99682900 }}, - //{1.00000e+07, 353.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99958936, 0.00041064, { 0.00108254, 0.00160931, 0.99723579 }, { 0.87159649, 0.12018752, 0.00661262 }}, - //{1.00000e+07, 278.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00020630, 0.99979370, { 0.00181934, 0.00244237, 0.99161209 }, { 0.88246568, 0.05855458, 0.00014546 }}, - //{1.00000e+07, 293.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.88228400, 0.05854300, 0.00035000 }, { 0.88228400, 0.05854300, 0.00035000 }}, - //{1.00000e+07, 303.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.88228400, 0.05854300, 0.00035000 }, { 0.88228400, 0.05854300, 0.00035000 }}, - //{1.00000e+07, 293.15, { 0.00000000, 0.00000500, 0.00000000, 0.99999500 }, 1.00000000, 0.00000000, { 0.00000000, 0.00000500, 0.99999500 }, { 0.00000000, 0.00071931, 0.99928069 }}, - //{1.00000e+07, 293.15, { 0.00000000, 0.02572500, 0.00000000, 0.97427500 }, 1.00000000, 0.00000000, { 0.00000000, 0.02572500, 0.97427500 }, { 0.00000000, 0.02572500, 0.97427500 }}, - //{1.00000e+07, 293.15, { 0.00000000, 0.02572600, 0.00000000, 0.97427400 }, 0.99999969, 0.00000031, { 0.00000000, 0.02572570, 0.97427430 }, { 0.00000000, 0.99724814, 0.00275186 }}, - //{1.00000e+07, 293.15, { 0.99999500, 0.00000000, 0.00000000, 0.00000500 }, 0.00000000, 1.00000000, { 0.99999500, 0.00000000, 0.00000500 }, { 0.99999500, 0.00000000, 0.00000500 }}, - //{1.00000e+07, 288.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00008980, 0.99991020, { 0.00168896, 0.00000000, 0.99831104 }, { 0.99975363, 0.00000000, 0.00024637 }}, - //{1.00000e+07, 293.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.99966400, 0.00000000, 0.00033600 }, { 0.99966400, 0.00000000, 0.00033600 }}, - //{1.00000e+07, 303.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.99966400, 0.00000000, 0.00033600 }, { 0.99966400, 0.00000000, 0.00033600 }} - {4.7343674e+06, 403.29381020, { 0.718369, 0.0399971, 5.58409e-14, 0.241633 }, 0.99999969, 0.00000031, { 0.00000000, 0.02572570, 0.97427430 }, { 0.00000000, 0.99724814, 0.00275186 }}, + {2.01675e+07, 349.15, { 0.00000000, 0.00180029, 0.00073062, 0.99746900 }, 1.00000000, 0.00000000, { 0.00000000, 0.00180029, 0.99746900 }, { 0.00000000, 0.00180029, 0.99746900 }}, + {1.07250e+07, 349.15, { 0.42400000, 0.05624000, 0.05624000, 0.46351000 }, 0.46391991, 0.53608009, { 0.00109926, 0.00153071, 0.99250187 }, { 0.78998321, 0.10358608, 0.00573284 }}, + {1.06611e+07, 349.15, { 0.42341000, 0.05616000, 0.05616000, 0.46426000 }, 0.46465757, 0.53534243, { 0.00109380, 0.00152509, 0.99252663 }, { 0.78997286, 0.10358214, 0.00575264 }}, + {1.92943e+07, 349.15, { 0.62210000, 0.08283000, 0.08283000, 0.21224000 }, 0.21083142, 0.78916858, { 0.00172629, 0.00206379, 0.99021290 }, { 0.78783679, 0.10440721, 0.00439958 }}, + {2.00000e+07, 349.15, { 0.75000000, 0.10000000, 0.10000000, 0.05000000 }, 0.04630725, 0.95369275, { 0.00176884, 0.00209963, 0.99002996 }, { 0.78633091, 0.10475362, 0.00435616 }}, + {1.99953e+07, 349.15, { 0.96334500, 0.01267200, 0.01266500, 0.01131700 }, 0.00782092, 0.99217908, { 0.00199275, 0.00025091, 0.99699415 }, { 0.97092389, 0.01276992, 0.00354735 }}, + {1.99971e+07, 349.15, { 0.96329100, 0.01267200, 0.01266500, 0.01137300 }, 0.00787742, 0.99212258, { 0.00199287, 0.00025093, 0.99699395 }, { 0.97092271, 0.01277061, 0.00354719 }}, + {1.00000e+07, 293.15, { 0.75000000, 0.05000000, 0.05000000, 0.15000000 }, 0.15072066, 0.84927934, { 0.00150781, 0.00166788, 0.99309883 }, { 0.88283407, 0.05857745, 0.00037619 }}, + {1.00000e+07, 288.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.00144000, 0.00165800, 0.99682900 }}, + {1.00000e+07, 293.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 1.00000000, 0.00000000, { 0.00144000, 0.00165800, 0.99682900 }, { 0.00144000, 0.00165800, 0.99682900 }}, + {1.00000e+07, 353.15, { 0.00144000, 0.00165800, 0.00007300, 0.99682900 }, 0.99958936, 0.00041064, { 0.00108254, 0.00160931, 0.99723579 }, { 0.87159649, 0.12018752, 0.00661262 }}, + {1.00000e+07, 278.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00020630, 0.99979370, { 0.00181934, 0.00244237, 0.99161209 }, { 0.88246568, 0.05855458, 0.00014546 }}, + {1.00000e+07, 293.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.88228400, 0.05854300, 0.00035000 }, { 0.88228400, 0.05854300, 0.00035000 }}, + {1.00000e+07, 303.15, { 0.88228400, 0.05854300, 0.05882300, 0.00035000 }, 0.00000000, 1.00000000, { 0.88228400, 0.05854300, 0.00035000 }, { 0.88228400, 0.05854300, 0.00035000 }}, + {1.00000e+07, 293.15, { 0.00000000, 0.00000500, 0.00000000, 0.99999500 }, 1.00000000, 0.00000000, { 0.00000000, 0.00000500, 0.99999500 }, { 0.00000000, 0.00071931, 0.99928069 }}, + {1.00000e+07, 293.15, { 0.00000000, 0.02572500, 0.00000000, 0.97427500 }, 1.00000000, 0.00000000, { 0.00000000, 0.02572500, 0.97427500 }, { 0.00000000, 0.02572500, 0.97427500 }}, + {1.00000e+07, 293.15, { 0.00000000, 0.02572600, 0.00000000, 0.97427400 }, 0.99999969, 0.00000031, { 0.00000000, 0.02572570, 0.97427430 }, { 0.00000000, 0.99724814, 0.00275186 }}, + {1.00000e+07, 293.15, { 0.99999500, 0.00000000, 0.00000000, 0.00000500 }, 0.00000000, 1.00000000, { 0.99999500, 0.00000000, 0.00000500 }, { 0.99999500, 0.00000000, 0.00000500 }}, + {1.00000e+07, 288.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00008980, 0.99991020, { 0.00168896, 0.00000000, 0.99831104 }, { 0.99975363, 0.00000000, 0.00024637 }}, + {1.00000e+07, 293.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.99966400, 0.00000000, 0.00033600 }, { 0.99966400, 0.00000000, 0.00033600 }}, + {1.00000e+07, 303.15, { 0.99966400, 0.00000000, 0.00000000, 0.00033600 }, 0.00000000, 1.00000000, { 0.99966400, 0.00000000, 0.00033600 }, { 0.99966400, 0.00000000, 0.00033600 }} }) ); -/* INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlashModel, SoaveRedlichKwong2, @@ -465,7 +429,6 @@ INSTANTIATE_TEST_SUITE_P( {1.00000e+07, 293.15, { 0.98696000, 0.01304000 }, 0.00000154, 0.99999846, { 0.08177948, 0.91822052, 0.91822052 }, { 0.98696139, 0.01303861, 0.01303861 }} }) ); -*/ /* UNCRUSTIFY-ON */ diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp index 30044563a72..9ac72d272de 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp @@ -126,7 +126,7 @@ TEST_P( PengRobinson, testStabilityTest ) } TEST_P( SoaveRedlichKwong, testStabilityTest ) { - // testStability( GetParam() ); + testStability( GetParam() ); } //------------------------------------------------------------------------------- @@ -143,8 +143,8 @@ INSTANTIATE_TEST_SUITE_P(StabilityTest, PengRobinson, {5.0e+06, 353.15, 0.4000, false, 0.40000000 }, {2.0e+07, 297.15, 0.4000, false, 0.40000000 }, {2.0e+07, 353.15, 0.4000, false, 0.40000001 }, - {5.0e+06, 297.15, 0.7860, true, 0.31984391 }, - {5.0e+06, 297.15, 0.7870, true, 0.32331543 }, + {5.0e+06, 297.15, 0.7860, false, 0.31984391 }, + {5.0e+06, 297.15, 0.7870, false, 0.32331543 }, {5.0e+06, 297.15, 0.3200, true, 0.78604645 }, {5.0e+06, 297.15, 0.3220, true, 0.78662927 } }) diff --git a/src/coreComponents/schema/schema.xsd b/src/coreComponents/schema/schema.xsd index 8bcb4699312..60988fae269 100644 --- a/src/coreComponents/schema/schema.xsd +++ b/src/coreComponents/schema/schema.xsd @@ -5860,6 +5860,8 @@ Information output from lower logLevels is added with the desired log level + + @@ -5922,6 +5924,8 @@ Information output from lower logLevels is added with the desired log level + + @@ -5961,6 +5965,8 @@ Information output from lower logLevels is added with the desired log level + + @@ -6011,6 +6017,8 @@ Information output from lower logLevels is added with the desired log level + + From f90e5c2d2d40fff518f6a711ea7d5540b5a5e22c Mon Sep 17 00:00:00 2001 From: dkachuma Date: Fri, 8 Aug 2025 15:52:13 -0500 Subject: [PATCH 26/28] Save N+1 solution --- .../functions/NegativeTwoPhaseFlash_impl.hpp | 64 ++++- .../functions/StabilityTest_impl.hpp | 2 +- .../unitTests/TestFluidUtilities.hpp | 7 +- .../testNegativeTwoPhaseFlash9Comp.cpp | 256 +++++++++--------- .../testNegativeTwoPhaseFlashJacobian.cpp | 57 +++- 5 files changed, 242 insertions(+), 144 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index 5cca5ce92d4..a77e9d93b3d 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -55,7 +55,7 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, integer const numDofs = numComps + 2; StackArray< real64, 2, 3*maxNumComps > workSpace( 3, numComps ); - StackArray< real64, 1, maxNumComps+1 > residualSpace( numComps ); + StackArray< real64, 1, maxNumComps+1 > residualSpace( numComps+1 ); arraySlice1d< real64 > logLiquidFugacity = workSpace[0]; arraySlice1d< real64 > logVapourFugacity = workSpace[1]; arraySlice1d< real64 > residual = residualSpace.toSlice(); @@ -103,6 +103,18 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, logVapourFugacity, residual ); +std::cout +<< std::setw(3) << iterationCount << " " +<< "SSI" +<< std::scientific << std::setprecision(5) << std::setw(12) << error << " " +<< std::fixed << std::setprecision(8) << std::setw(12) << vapourPhaseMoleFraction << " " +<< std::fixed << std::setprecision(5) << liquidComposition << " " +<< std::fixed << std::setprecision(5) << vapourComposition << " " +<< "\n"; + if( error < flashSSITolerance ) + { + break; + } // Update K-values for( integer const ic : presentComponents ) { @@ -112,19 +124,20 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, // Check convergence converged = ( error < flashTolerance ); + // Don't switch to Newton if we are in the "negative flash" range if( error < flashSSITolerance ) { break; } } - +std::cout << std::scientific << std::setprecision(8) << kVapourLiquid.toSliceConst() << "\n"; // Start Newton iterations StackArray< real64, 3, 2*maxNumComps * maxNumDofs > logFugacityDerivs( 2, numComps, numDofs ); StackArray< real64, 2, (maxNumComps+1) * (maxNumComps+1) > jacobian( numComps+1, numComps+1 ); arraySlice2d< real64 > const logLiquidFugacityDerivs = logFugacityDerivs[0]; arraySlice2d< real64 > const logVapourFugacityDerivs = logFugacityDerivs[1]; - for(; ( !converged ) && (iterationCount < maxIterations); ++iterationCount ) + for(iterationCount++; ( !converged ) && (iterationCount < maxIterations); ++iterationCount ) { real64 const error = calculateResidualAndJacobian( numComps, pressure, @@ -148,7 +161,41 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, { jacobian( ic, ic ) = 1.0; } - + /* +std::cout << std::scientific << std::setprecision(5); +for (integer ic = 0; ic < numComps; ++ic) +{ + real64 const zi = composition[ic]; + real64 const xi = liquidComposition[ic]; + real64 const yi = vapourComposition[ic]; +//std::cout << ic << " " +//<< std::scientific << std::setprecision(5) << xi << " " << yi << " " << zi << "\n"; + if (LvArray::math::min(LvArray::math::min(xi, yi), zi) < 1e-4) + { +for (integer jc = 0; jc <= numComps; ++jc) +{ + jacobian( ic, jc ) = 0.0; + jacobian( jc, ic ) = 0.0; +} +jacobian( ic, ic ) = 1.0; + } +} */ +std::cout << "---------------------------------------------\n"; +std::cout << std::scientific << std::setprecision(5); +for (integer ic = 0; ic <= numComps; ++ic) +{ + std::cout << jacobian[ic] << "\n"; +} +std::cout << "---------------------------------------------\n"; +std::cout +<< std::setw(3) << iterationCount << " " +<< "NEW" +<< std::scientific << std::setprecision(5) << std::setw(12) << error << " " +<< std::fixed << std::setprecision(8) << std::setw(12) << vapourPhaseMoleFraction << " " +//<< std::fixed << std::setprecision(5) << liquidComposition << " " +//<< std::fixed << std::setprecision(5) << vapourComposition << " " +<< std::scientific << std::setprecision(5) << residual << " " +<< "\n"; // Solve for next step solveLinearSystem( jacobian.toSlice(), residual ); // Update K-values @@ -159,6 +206,15 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, vapourPhaseMoleFraction -= residual[numComps]; // Check convergence converged = ( error < flashTolerance ); +std::cout +<< std::setw(3) << iterationCount << " " +<< "NEW" +<< std::scientific << std::setprecision(5) << std::setw(12) << error << " " +<< std::fixed << std::setprecision(8) << std::setw(12) << vapourPhaseMoleFraction << " " +//<< std::fixed << std::setprecision(5) << liquidComposition << " " +//<< std::fixed << std::setprecision(5) << vapourComposition << " " +<< std::scientific << std::setprecision(5) << residual << " " +<< "\n"; } // Test if we have converged to a null or trivial solution diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp index d95f0ba17aa..014c0d85512 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp @@ -167,7 +167,7 @@ bool StabilityTest::compute( integer const numComps, } // Start with Newton iterations - for(; (!converged) && (iterationCount < maxIterations); ++iterationCount ) + for(iterationCount++; (!converged) && (iterationCount < maxIterations); ++iterationCount ) { for( integer const ic : presentComponents ) { diff --git a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp index 2f2698d28fc..664c40e5025 100644 --- a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp +++ b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp @@ -108,9 +108,8 @@ void testNumericalDerivative( real64 const x, selectedDerivative = deriv; } } - checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, - GEOS_FMT( "Numerical derivative for component {}", i ) ); - /* + // checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, + // GEOS_FMT( "Numerical derivative for component {}", i ) ); ((void)relTolerance); ((void)absTolerance); real64 const maxV = 1.0e-14 + LvArray::math::max( LvArray::math::abs( selectedDerivative ), LvArray::math::abs( derivatives[i] )); @@ -125,7 +124,7 @@ void testNumericalDerivative( real64 const x, << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << (selectedDerivative - derivatives[i])/maxV << " " << "\n"; } - std::cout << "----------------------------------------------------------\n";*/ + std::cout << "----------------------------------------------------------\n"; } /** diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp index 00a60a52b7a..df795bff03c 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp @@ -90,6 +90,8 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); auto const * flashParameters = parameters->get< FlashParameters >(); + flashParameters->m_discreteParameters[FlashParameters::FLASH_MAX_ITERATIONS] = 20; + //flashParameters->m_continuousParameters[FlashParameters::SSI_TOLERANCE] = 1.0e-6; bool status = NegativeTwoPhaseFlash::compute( numComps, @@ -305,13 +307,13 @@ std::unique_ptr< TestFluid< numComps > > NegativeTwoPhaseFlashTest9CompFixture< } using PengRobinson = NegativeTwoPhaseFlashTest9CompFixture< EquationOfStateType::PengRobinson >; -using SoaveRedlichKwong = NegativeTwoPhaseFlashTest9CompFixture< EquationOfStateType::SoaveRedlichKwong >; +//using SoaveRedlichKwong = NegativeTwoPhaseFlashTest9CompFixture< EquationOfStateType::SoaveRedlichKwong >; TEST_P( PengRobinson, testNegativeFlash ) { testFlash( GetParam() ); } - +/* TEST_P( PengRobinson, testNegativeFlashDerivatives ) { testFlashDerivatives( GetParam() ); @@ -326,7 +328,7 @@ TEST_P( SoaveRedlichKwong, testNegativeFlashDerivatives ) { testFlashDerivatives( GetParam() ); } - +*/ //------------------------------------------------------------------------------- // Data //------------------------------------------------------------------------------- @@ -336,131 +338,131 @@ TEST_P( SoaveRedlichKwong, testNegativeFlashDerivatives ) INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlash, PengRobinson, ::testing::Values( - FlashData( 1.000000e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+05, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.798353, {0.000363, 0.839010}, {0.011181, 0.000020} ), - FlashData( 1.000000e+05, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998685, {0.000228, 0.938644}, {0.007035, 0.000022} ), - FlashData( 1.013250e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.013250e+05, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.798070, {0.000368, 0.837836}, {0.011184, 0.000020} ), - FlashData( 1.013250e+05, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998684, {0.000231, 0.937856}, {0.007035, 0.000022} ), - FlashData( 1.000000e+06, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+06, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.700780, {0.003486, 0.565464}, {0.011355, 0.000003} ), - FlashData( 1.000000e+06, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.997643, {0.002159, 0.531971}, {0.007037, 0.000002} ), - FlashData( 1.000000e+07, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+07, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.349114, {0.010010, 0.259905}, {0.007116, 0.000090} ), - FlashData( 1.000000e+07, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.991703, {0.009755, 0.140969}, {0.007003, 0.000087} ), - FlashData( 1.500000e+07, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.500000e+07, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.176058, {0.009422, 0.205086}, {0.007026, 0.001256} ), - FlashData( 1.500000e+07, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.009422, 0.205089}, {0.007026, 0.001256} ), - FlashData( 5.000000e+07, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+08, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.000000e+05, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.001168, {0.000348, 0.839991}, {0.013059, 0.000053} ), - FlashData( 1.000000e+05, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.805671, {0.000295, 0.870461}, {0.011100, 0.000055} ), - FlashData( 1.000000e+05, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998750, {0.000187, 0.957531}, {0.007035, 0.000059} ), - FlashData( 1.013250e+05, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.001057, {0.000350, 0.839898}, {0.012947, 0.000052} ), - FlashData( 1.013250e+05, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.805431, {0.000299, 0.869390}, {0.011102, 0.000054} ), - FlashData( 1.013250e+05, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998749, {0.000189, 0.956982}, {0.007035, 0.000058} ), - FlashData( 1.000000e+06, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+06, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.719045, {0.002880, 0.602213}, {0.011391, 0.000007} ), - FlashData( 1.000000e+06, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998097, {0.001770, 0.656139}, {0.007036, 0.000007} ), - FlashData( 1.000000e+07, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+07, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.391974, {0.009806, 0.278198}, {0.007750, 0.000123} ), - FlashData( 1.000000e+07, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.994318, {0.008887, 0.201207}, {0.007015, 0.000113} ), - FlashData( 1.500000e+07, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.500000e+07, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.231493, {0.009474, 0.219807}, {0.007427, 0.001195} ), - FlashData( 1.500000e+07, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999406, {0.009004, 0.228228}, {0.007025, 0.001121} ), - FlashData( 5.000000e+07, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+05, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.002535, {0.000327, 0.841142}, {0.014448, 0.000119} ), - FlashData( 1.000000e+05, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.811028, {0.000249, 0.894832}, {0.011039, 0.000125} ), - FlashData( 1.000000e+05, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998841, {0.000158, 0.968326}, {0.007034, 0.000134} ), - FlashData( 1.013250e+05, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.002401, {0.000329, 0.841029}, {0.014353, 0.000118} ), - FlashData( 1.013250e+05, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.810823, {0.000253, 0.893869}, {0.011041, 0.000124} ), - FlashData( 1.013250e+05, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998839, {0.000161, 0.967914}, {0.007034, 0.000132} ), - FlashData( 1.000000e+06, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+06, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.733594, {0.002451, 0.635078}, {0.011378, 0.000016} ), - FlashData( 1.000000e+06, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998313, {0.001505, 0.734457}, {0.007035, 0.000017} ), - FlashData( 1.000000e+07, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+07, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.426139, {0.009539, 0.294719}, {0.008274, 0.000169} ), - FlashData( 1.000000e+07, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.995698, {0.008127, 0.256601}, {0.007021, 0.000153} ), - FlashData( 1.500000e+07, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.500000e+07, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.275063, {0.009454, 0.232929}, {0.007803, 0.001242} ), - FlashData( 1.500000e+07, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999403, {0.008577, 0.252667}, {0.007025, 0.001106} ), - FlashData( 5.000000e+07, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+05, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.009514, {0.000227, 0.847062}, {0.014475, 0.000776} ), - FlashData( 1.000000e+05, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.820830, {0.000171, 0.940506}, {0.010927, 0.000840} ), - FlashData( 1.000000e+05, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999605, {0.000110, 0.982954}, {0.007029, 0.000869} ), - FlashData( 1.013250e+05, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.009213, {0.000231, 0.846804}, {0.014528, 0.000766} ), - FlashData( 1.013250e+05, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.820694, {0.000173, 0.939845}, {0.010929, 0.000829} ), - FlashData( 1.013250e+05, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999594, {0.000111, 0.982731}, {0.007029, 0.000858} ), - FlashData( 1.000000e+06, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+06, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.763803, {0.001692, 0.716010}, {0.011260, 0.000105} ), - FlashData( 1.000000e+06, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998655, {0.001048, 0.848573}, {0.007034, 0.000115} ), - FlashData( 1.000000e+07, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+07, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.500392, {0.008630, 0.338259}, {0.009369, 0.000406} ), - FlashData( 1.000000e+07, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.997667, {0.006476, 0.384497}, {0.007027, 0.000360} ), - FlashData( 1.500000e+07, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.500000e+07, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.367748, {0.009160, 0.266615}, {0.008725, 0.001720} ), - FlashData( 1.500000e+07, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 5.000000e+07, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+05, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.031155, {0.000097, 0.865831}, {0.008647, 0.004929} ), - FlashData( 1.000000e+05, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.829852, {0.000120, 0.968392}, {0.010821, 0.005338} ), - FlashData( 1.000000e+05, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.013250e+05, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.030488, {0.000099, 0.865241}, {0.008755, 0.004866} ), - FlashData( 1.013250e+05, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.829724, {0.000121, 0.968002}, {0.010822, 0.005269} ), - FlashData( 1.013250e+05, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.000000e+06, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+06, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.787992, {0.001191, 0.795638}, {0.011101, 0.000658} ), - FlashData( 1.000000e+06, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999382, {0.000748, 0.906103}, {0.007030, 0.000696} ), - FlashData( 1.000000e+07, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+07, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.567463, {0.007479, 0.389712}, {0.010159, 0.001120} ), - FlashData( 1.000000e+07, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999429, {0.005131, 0.493383}, {0.007027, 0.000975} ), - FlashData( 1.500000e+07, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.500000e+07, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.449715, {0.008545, 0.304966}, {0.009556, 0.003072} ), - FlashData( 1.500000e+07, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.000000e+05, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.053370, {0.000054, 0.885524}, {0.005836, 0.013991} ), - FlashData( 1.000000e+05, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.839835, {0.000099, 0.977972}, {0.010698, 0.014959} ), - FlashData( 1.000000e+05, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.013250e+05, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.052543, {0.000056, 0.884773}, {0.005903, 0.013808} ), - FlashData( 1.013250e+05, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.839621, {0.000100, 0.977689}, {0.010700, 0.014767} ), - FlashData( 1.013250e+05, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.000000e+06, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+06, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.799362, {0.000988, 0.836026}, {0.011011, 0.001828} ), - FlashData( 1.000000e+06, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.000000e+07, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+07, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.602229, {0.006805, 0.422215}, {0.010450, 0.002084} ), - FlashData( 1.000000e+07, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.500000e+07, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.500000e+07, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.492074, {0.008098, 0.328602}, {0.009931, 0.004663} ), - FlashData( 1.500000e+07, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.000000e+05, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.078426, {0.000034, 0.907428}, {0.004230, 0.035040} ), - FlashData( 1.000000e+05, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.860286, {0.000083, 0.983960}, {0.010448, 0.036880} ), - FlashData( 1.000000e+05, 3.931500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.013250e+05, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.077531, {0.000035, 0.906620}, {0.004269, 0.034580} ), - FlashData( 1.013250e+05, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.859825, {0.000084, 0.983745}, {0.010454, 0.036407} ), - FlashData( 1.000000e+06, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+06, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.808966, {0.000846, 0.866838}, {0.010926, 0.004456} ), - FlashData( 1.000000e+07, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.630979, {0.006236, 0.452193}, {0.010617, 0.003695} ), - FlashData( 1.500000e+07, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.527277, {0.007678, 0.350047}, {0.010185, 0.007065} ), - FlashData( 1.500000e+07, 3.931500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 5.000000e+07, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.013250e+05, 5.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.000000e+06, 5.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.013401, {0.000295, 0.847670}, {0.005333, 0.201455} ), - FlashData( 1.000000e+06, 5.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), - FlashData( 1.000000e+07, 5.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+07, 5.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.783614, {0.004654, 0.554668}, {0.010200, 0.062757} ), - FlashData( 1.500000e+07, 5.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.500000e+07, 5.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.717160, {0.006496, 0.400841}, {0.009988, 0.077843} ), - FlashData( 1.013250e+05, 5.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.000000e+06, 5.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.166124, {0.000103, 0.906268}, {0.001666, 0.501402} ), - FlashData( 1.000000e+07, 5.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.947056, {0.004797, 0.541766}, {0.009235, 0.148372} ), - FlashData( 8.000000e+07, 8.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 8.000000e+07, 8.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), - FlashData( 8.000000e+07, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - FlashData( 1.000000e+08, 8.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - FlashData( 1.000000e+08, 8.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), - FlashData( 1.000000e+08, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ) + //FlashData( 1.000000e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+05, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.798353, {0.000363, 0.839010}, {0.011181, 0.000020} ), + //FlashData( 1.000000e+05, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998685, {0.000228, 0.938644}, {0.007035, 0.000022} ), + //FlashData( 1.013250e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.013250e+05, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.798070, {0.000368, 0.837836}, {0.011184, 0.000020} ), + FlashData( 1.013250e+05, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998684, {0.000231, 0.937856}, {0.007035, 0.000022} ) + //FlashData( 1.000000e+06, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ) + //FlashData( 1.000000e+06, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.700780, {0.003486, 0.565464}, {0.011355, 0.000003} ), + //FlashData( 1.000000e+06, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.997643, {0.002159, 0.531971}, {0.007037, 0.000002} ), + //FlashData( 1.000000e+07, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ) + //FlashData( 1.000000e+07, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.349114, {0.010010, 0.259905}, {0.007116, 0.000090} ), + //FlashData( 1.000000e+07, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.991703, {0.009755, 0.140969}, {0.007003, 0.000087} ), + //FlashData( 1.500000e+07, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.500000e+07, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.176058, {0.009422, 0.205086}, {0.007026, 0.001256} ), + //FlashData( 1.500000e+07, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.009422, 0.205089}, {0.007026, 0.001256} ), + //FlashData( 5.000000e+07, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+08, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.000000e+05, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.001168, {0.000348, 0.839991}, {0.013059, 0.000053} ), + //FlashData( 1.000000e+05, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.805671, {0.000295, 0.870461}, {0.011100, 0.000055} ), + //FlashData( 1.000000e+05, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998750, {0.000187, 0.957531}, {0.007035, 0.000059} ), + //FlashData( 1.013250e+05, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.001057, {0.000350, 0.839898}, {0.012947, 0.000052} ), + //FlashData( 1.013250e+05, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.805431, {0.000299, 0.869390}, {0.011102, 0.000054} ), + //FlashData( 1.013250e+05, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998749, {0.000189, 0.956982}, {0.007035, 0.000058} ), + //FlashData( 1.000000e+06, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+06, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.719045, {0.002880, 0.602213}, {0.011391, 0.000007} ), + //FlashData( 1.000000e+06, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998097, {0.001770, 0.656139}, {0.007036, 0.000007} ), + //FlashData( 1.000000e+07, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+07, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.391974, {0.009806, 0.278198}, {0.007750, 0.000123} ), + //FlashData( 1.000000e+07, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.994318, {0.008887, 0.201207}, {0.007015, 0.000113} ), + //FlashData( 1.500000e+07, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.500000e+07, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.231493, {0.009474, 0.219807}, {0.007427, 0.001195} ), + //FlashData( 1.500000e+07, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999406, {0.009004, 0.228228}, {0.007025, 0.001121} ), + //FlashData( 5.000000e+07, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+05, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.002535, {0.000327, 0.841142}, {0.014448, 0.000119} ), + //FlashData( 1.000000e+05, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.811028, {0.000249, 0.894832}, {0.011039, 0.000125} ), + //FlashData( 1.000000e+05, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998841, {0.000158, 0.968326}, {0.007034, 0.000134} ), + //FlashData( 1.013250e+05, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.002401, {0.000329, 0.841029}, {0.014353, 0.000118} ), + //FlashData( 1.013250e+05, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.810823, {0.000253, 0.893869}, {0.011041, 0.000124} ), + //FlashData( 1.013250e+05, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998839, {0.000161, 0.967914}, {0.007034, 0.000132} ), + //FlashData( 1.000000e+06, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+06, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.733594, {0.002451, 0.635078}, {0.011378, 0.000016} ), + //FlashData( 1.000000e+06, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998313, {0.001505, 0.734457}, {0.007035, 0.000017} ), + //FlashData( 1.000000e+07, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+07, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.426139, {0.009539, 0.294719}, {0.008274, 0.000169} ), + //FlashData( 1.000000e+07, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.995698, {0.008127, 0.256601}, {0.007021, 0.000153} ), + //FlashData( 1.500000e+07, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.500000e+07, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.275063, {0.009454, 0.232929}, {0.007803, 0.001242} ), + //FlashData( 1.500000e+07, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999403, {0.008577, 0.252667}, {0.007025, 0.001106} ), + //FlashData( 5.000000e+07, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+05, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.009514, {0.000227, 0.847062}, {0.014475, 0.000776} ), + //FlashData( 1.000000e+05, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.820830, {0.000171, 0.940506}, {0.010927, 0.000840} ), + //FlashData( 1.000000e+05, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999605, {0.000110, 0.982954}, {0.007029, 0.000869} ), + //FlashData( 1.013250e+05, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.009213, {0.000231, 0.846804}, {0.014528, 0.000766} ), + //FlashData( 1.013250e+05, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.820694, {0.000173, 0.939845}, {0.010929, 0.000829} ), + //FlashData( 1.013250e+05, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999594, {0.000111, 0.982731}, {0.007029, 0.000858} ), + //FlashData( 1.000000e+06, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+06, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.763803, {0.001692, 0.716010}, {0.011260, 0.000105} ), + //FlashData( 1.000000e+06, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998655, {0.001048, 0.848573}, {0.007034, 0.000115} ), + //FlashData( 1.000000e+07, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+07, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.500392, {0.008630, 0.338259}, {0.009369, 0.000406} ), + //FlashData( 1.000000e+07, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.997667, {0.006476, 0.384497}, {0.007027, 0.000360} ), + //FlashData( 1.500000e+07, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.500000e+07, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.367748, {0.009160, 0.266615}, {0.008725, 0.001720} ), + //FlashData( 1.500000e+07, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 5.000000e+07, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+05, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.031155, {0.000097, 0.865831}, {0.008647, 0.004929} ), + //FlashData( 1.000000e+05, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.829852, {0.000120, 0.968392}, {0.010821, 0.005338} ), + //FlashData( 1.000000e+05, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.013250e+05, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.030488, {0.000099, 0.865241}, {0.008755, 0.004866} ), + //FlashData( 1.013250e+05, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.829724, {0.000121, 0.968002}, {0.010822, 0.005269} ), + //FlashData( 1.013250e+05, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.000000e+06, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+06, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.787992, {0.001191, 0.795638}, {0.011101, 0.000658} ), + //FlashData( 1.000000e+06, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999382, {0.000748, 0.906103}, {0.007030, 0.000696} ), + //FlashData( 1.000000e+07, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+07, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.567463, {0.007479, 0.389712}, {0.010159, 0.001120} ), + //FlashData( 1.000000e+07, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999429, {0.005131, 0.493383}, {0.007027, 0.000975} ), + //FlashData( 1.500000e+07, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.500000e+07, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.449715, {0.008545, 0.304966}, {0.009556, 0.003072} ), + //FlashData( 1.500000e+07, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.000000e+05, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.053370, {0.000054, 0.885524}, {0.005836, 0.013991} ), + //FlashData( 1.000000e+05, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.839835, {0.000099, 0.977972}, {0.010698, 0.014959} ), + //FlashData( 1.000000e+05, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.013250e+05, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.052543, {0.000056, 0.884773}, {0.005903, 0.013808} ), + //FlashData( 1.013250e+05, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.839621, {0.000100, 0.977689}, {0.010700, 0.014767} ), + //FlashData( 1.013250e+05, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.000000e+06, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+06, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.799362, {0.000988, 0.836026}, {0.011011, 0.001828} ), + //FlashData( 1.000000e+06, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.000000e+07, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+07, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.602229, {0.006805, 0.422215}, {0.010450, 0.002084} ), + //FlashData( 1.000000e+07, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.500000e+07, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.500000e+07, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.492074, {0.008098, 0.328602}, {0.009931, 0.004663} ), + //FlashData( 1.500000e+07, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.000000e+05, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.078426, {0.000034, 0.907428}, {0.004230, 0.035040} ), + //FlashData( 1.000000e+05, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.860286, {0.000083, 0.983960}, {0.010448, 0.036880} ), + //FlashData( 1.000000e+05, 3.931500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.013250e+05, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.077531, {0.000035, 0.906620}, {0.004269, 0.034580} ), + //FlashData( 1.013250e+05, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.859825, {0.000084, 0.983745}, {0.010454, 0.036407} ), + //FlashData( 1.000000e+06, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+06, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.808966, {0.000846, 0.866838}, {0.010926, 0.004456} ), + //FlashData( 1.000000e+07, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.630979, {0.006236, 0.452193}, {0.010617, 0.003695} ), + //FlashData( 1.500000e+07, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.527277, {0.007678, 0.350047}, {0.010185, 0.007065} ), + //FlashData( 1.500000e+07, 3.931500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 5.000000e+07, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.013250e+05, 5.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.000000e+06, 5.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.013401, {0.000295, 0.847670}, {0.005333, 0.201455} ), + //FlashData( 1.000000e+06, 5.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), + //FlashData( 1.000000e+07, 5.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+07, 5.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.783614, {0.004654, 0.554668}, {0.010200, 0.062757} ), + //FlashData( 1.500000e+07, 5.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.500000e+07, 5.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.717160, {0.006496, 0.400841}, {0.009988, 0.077843} ), + //FlashData( 1.013250e+05, 5.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.000000e+06, 5.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.166124, {0.000103, 0.906268}, {0.001666, 0.501402} ), + //FlashData( 1.000000e+07, 5.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.947056, {0.004797, 0.541766}, {0.009235, 0.148372} ), + //FlashData( 8.000000e+07, 8.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 8.000000e+07, 8.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), + //FlashData( 8.000000e+07, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + //FlashData( 1.000000e+08, 8.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + //FlashData( 1.000000e+08, 8.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), + //FlashData( 1.000000e+08, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ) ) ); - +/* INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlash, SoaveRedlichKwong, ::testing::Values( @@ -571,7 +573,7 @@ INSTANTIATE_TEST_SUITE_P( FlashData( 1.000000e+08, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ) ) ); - +*/ /* UNCRUSTIFY-ON */ } // testing diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashJacobian.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashJacobian.cpp index 5fea704c54c..cd7572442eb 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashJacobian.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashJacobian.cpp @@ -50,6 +50,33 @@ struct FluidData< 4 > } }; +template<> +struct FluidData< 9 > +{ +static std::unique_ptr< TestFluid< 9 > > createFluid() +{ + std::unique_ptr< TestFluid< 9 > > fluid = TestFluid< 9 >::create( {0, 0, 0, 0, 0, 0, 0, 0, 0} ); + // Manually populate + TestFluid< 9 >::populateArray( fluid->criticalPressure, Feed< 9 >{73.8659e5, 33.9439e5, 46.0421e5, 48.8387e5, 42.4552e5, 37.47e5, 33.5892e5, 30.1037e5, 20.549e5} ); + TestFluid< 9 >::populateArray( fluid->criticalTemperature, Feed< 9 >{304.7, 126.2, 190.6, 305.43, 369.8, 419.5, 465.9, 507.5, 678.8} ); + TestFluid< 9 >::populateArray( fluid->criticalVolume, Feed< 9 >{9.3999e-05, 9.0001e-05, 9.7999e-05, 1.4800e-04, 2.0000e-04, 2.5800e-04, 3.1000e-04, 3.5100e-04, 6.8243e-04} ); + TestFluid< 9 >::populateArray( fluid->acentricFactor, Feed< 9 >{0.225, 0.04, 0.013, 0.0986, 0.1524, 0.1956, 0.2413, 0.299, 0.5618} ); + TestFluid< 9 >::populateArray( fluid->molecularWeight, Feed< 9 >{44.01e-3, 28.01e-3, 16.04e-3, 30.07e-3, 44.1e-3, 58.12e-3, 72.15e-3, 84e-3, 173e-3} ); + TestFluid< 9 >::populateArray( fluid->volumeShift, Feed< 9 >{ -0.04958, -0.136012, -0.1486264, -0.10863408, -0.08349872, -0.06331568, -0.04196464, -0.0150072, 0.0000 } ); + fluid->setBinaryCoefficients( Feed< 36 >{ + 1.0000e-02, + 0.0000e+00, 3.7320e-03, + 0.0000e+00, 1.0000e-02, 0.0000e+00, + 0.0000e+00, 1.0000e-02, 0.0000e+00, 0.0000e+00, + 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, + 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, + 1.0000e-02, 0.0000e+00, 2.8000e-02, 1.0000e-02, 1.0000e-02, 0.0000e+00, 0.0000e+00, + 1.0000e-02, 0.0000e+00, 4.5320e-02, 1.0000e-02, 1.0000e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00 + } ); + return fluid; +} +}; + template< int NC > using FlashData = std::tuple< real64 const, // pressure @@ -120,15 +147,14 @@ class NegativeTwoPhaseFlashJacobianTestFixture : public ::testing::TestWithPara temperature, componentProperties, kValues ); + + std::array kv{ 5.50659394e-01, 6.30017745e+00, 2.74421602e+00, 4.80354013e-01, 1.56281500e-01, 5.21905616e-02, 1.78835233e-02, 5.75547635e-03, 9.74533928e-06 }; + for( integer ic = 0; ic < numComps; ++ic ) { - std::vector< real64 > x{0.03512106, 0.10723110, 0.10724847, 0.75039936}; - std::vector< real64 > y{0.99661534, 0.00094661, 0.00037503, 0.00206303}; - for( integer kc = 0; kc < numComps; ++kc ) - { - kValues[kc] = y[kc]/x[kc]; - } + kValues[ic] = kv[ic]; } + NegativeTwoPhaseFlash::calculateResidualAndJacobian( numComps, pressure, temperature, @@ -218,9 +244,11 @@ class NegativeTwoPhaseFlashJacobianTestFixture : public ::testing::TestWithPara std::unique_ptr< TestFluid< NC > > m_fluid{}; }; -using PengRobinson4 = NegativeTwoPhaseFlashJacobianTestFixture< 4, EquationOfStateType::PengRobinson, EquationOfStateType::PengRobinson >; -using SoreideWhitson4 = NegativeTwoPhaseFlashJacobianTestFixture< 4, EquationOfStateType::SoreideWhitson, EquationOfStateType::SoreideWhitson >; +//using PengRobinson4 = NegativeTwoPhaseFlashJacobianTestFixture< 4, EquationOfStateType::PengRobinson, EquationOfStateType::PengRobinson >; +//using SoreideWhitson4 = NegativeTwoPhaseFlashJacobianTestFixture< 4, EquationOfStateType::SoreideWhitson, EquationOfStateType::PengRobinson >; +using PengRobinson9 = NegativeTwoPhaseFlashJacobianTestFixture< 9, EquationOfStateType::PengRobinson, EquationOfStateType::PengRobinson >; +/* TEST_P( PengRobinson4, testJacobian ) { testJacobian( GetParam() ); @@ -230,6 +258,11 @@ TEST_P( SoreideWhitson4, testJacobian ) { testJacobian( GetParam() ); } +*/ +TEST_P( PengRobinson9, testJacobian ) +{ + testJacobian( GetParam() ); +} //------------------------------------------------------------------------------- // Data @@ -237,6 +270,7 @@ TEST_P( SoreideWhitson4, testJacobian ) /* UNCRUSTIFY-OFF */ +/* INSTANTIATE_TEST_SUITE_P(NegativeTwoPhaseFlashJacobian, PengRobinson4, ::testing::ValuesIn>({ {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 0.5} @@ -252,6 +286,13 @@ INSTANTIATE_TEST_SUITE_P(NegativeTwoPhaseFlashJacobian, SoreideWhitson4, {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 1.002} }) ); +*/ + +INSTANTIATE_TEST_SUITE_P(NegativeTwoPhaseFlashJacobian, PengRobinson9, + ::testing::ValuesIn>({ + {1.00000e+07, 278.15, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, -0.18866442} + }) +); /* UNCRUSTIFY-ON */ From c720c7301ae0d97d229996f4e50c925b57e28798 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Tue, 12 Aug 2025 22:07:15 -0500 Subject: [PATCH 27/28] Fix Jacobian --- .../functions/NegativeTwoPhaseFlash_impl.hpp | 69 +---- .../parameters/FlashParameters.cpp | 8 +- .../parameters/FlashParameters.hpp | 1 + .../unitTests/TestFluidUtilities.hpp | 102 +++---- .../testNegativeTwoPhaseFlash9Comp.cpp | 257 +++++++++--------- .../testNegativeTwoPhaseFlashJacobian.cpp | 90 +++--- 6 files changed, 229 insertions(+), 298 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp index a77e9d93b3d..8b8faf70ae6 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/NegativeTwoPhaseFlash_impl.hpp @@ -72,6 +72,7 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, integer const maxIterations = discreteFlashParameters[FlashParameters::FLASH_MAX_ITERATIONS]; real64 const flashTolerance = continuousFlashParameters[FlashParameters::FLASH_TOLERANCE]; real64 const flashSSITolerance = continuousFlashParameters[FlashParameters::SSI_TOLERANCE]; + real64 const negativeFlashTolerance = continuousFlashParameters[FlashParameters::NEGATIVE_FLASH_TOLERANCE]; // Initialise compositions to feed composition for( integer ic = 0; ic < numComps; ++ic ) @@ -80,6 +81,8 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, vapourComposition[ic] = composition[ic]; } + real64 const & V = vapourPhaseMoleFraction; + bool converged = false; localIndex iterationCount = 0; @@ -103,18 +106,6 @@ bool NegativeTwoPhaseFlash::compute( integer const numComps, logVapourFugacity, residual ); -std::cout -<< std::setw(3) << iterationCount << " " -<< "SSI" -<< std::scientific << std::setprecision(5) << std::setw(12) << error << " " -<< std::fixed << std::setprecision(8) << std::setw(12) << vapourPhaseMoleFraction << " " -<< std::fixed << std::setprecision(5) << liquidComposition << " " -<< std::fixed << std::setprecision(5) << vapourComposition << " " -<< "\n"; - if( error < flashSSITolerance ) - { - break; - } // Update K-values for( integer const ic : presentComponents ) { @@ -125,19 +116,20 @@ std::cout converged = ( error < flashTolerance ); // Don't switch to Newton if we are in the "negative flash" range - if( error < flashSSITolerance ) + // If we have reached the SSI tolerance and are not non-pysical switch to Newton + if( error < flashSSITolerance && -negativeFlashTolerance < V && -negativeFlashTolerance < 1.0-V ) { break; } } -std::cout << std::scientific << std::setprecision(8) << kVapourLiquid.toSliceConst() << "\n"; + // Start Newton iterations StackArray< real64, 3, 2*maxNumComps * maxNumDofs > logFugacityDerivs( 2, numComps, numDofs ); StackArray< real64, 2, (maxNumComps+1) * (maxNumComps+1) > jacobian( numComps+1, numComps+1 ); arraySlice2d< real64 > const logLiquidFugacityDerivs = logFugacityDerivs[0]; arraySlice2d< real64 > const logVapourFugacityDerivs = logFugacityDerivs[1]; - for(iterationCount++; ( !converged ) && (iterationCount < maxIterations); ++iterationCount ) + for( iterationCount++; ( !converged ) && (iterationCount < maxIterations); ++iterationCount ) { real64 const error = calculateResidualAndJacobian( numComps, pressure, @@ -161,60 +153,19 @@ std::cout << std::scientific << std::setprecision(8) << kVapourLiquid.toSliceCon { jacobian( ic, ic ) = 1.0; } - /* -std::cout << std::scientific << std::setprecision(5); -for (integer ic = 0; ic < numComps; ++ic) -{ - real64 const zi = composition[ic]; - real64 const xi = liquidComposition[ic]; - real64 const yi = vapourComposition[ic]; -//std::cout << ic << " " -//<< std::scientific << std::setprecision(5) << xi << " " << yi << " " << zi << "\n"; - if (LvArray::math::min(LvArray::math::min(xi, yi), zi) < 1e-4) - { -for (integer jc = 0; jc <= numComps; ++jc) -{ - jacobian( ic, jc ) = 0.0; - jacobian( jc, ic ) = 0.0; -} -jacobian( ic, ic ) = 1.0; - } -} */ -std::cout << "---------------------------------------------\n"; -std::cout << std::scientific << std::setprecision(5); -for (integer ic = 0; ic <= numComps; ++ic) -{ - std::cout << jacobian[ic] << "\n"; -} -std::cout << "---------------------------------------------\n"; -std::cout -<< std::setw(3) << iterationCount << " " -<< "NEW" -<< std::scientific << std::setprecision(5) << std::setw(12) << error << " " -<< std::fixed << std::setprecision(8) << std::setw(12) << vapourPhaseMoleFraction << " " -//<< std::fixed << std::setprecision(5) << liquidComposition << " " -//<< std::fixed << std::setprecision(5) << vapourComposition << " " -<< std::scientific << std::setprecision(5) << residual << " " -<< "\n"; + // Solve for next step solveLinearSystem( jacobian.toSlice(), residual ); + // Update K-values for( integer const ic : presentComponents ) { kVapourLiquid[ic] *= exp( -residual[ic] ); } vapourPhaseMoleFraction -= residual[numComps]; + // Check convergence converged = ( error < flashTolerance ); -std::cout -<< std::setw(3) << iterationCount << " " -<< "NEW" -<< std::scientific << std::setprecision(5) << std::setw(12) << error << " " -<< std::fixed << std::setprecision(8) << std::setw(12) << vapourPhaseMoleFraction << " " -//<< std::fixed << std::setprecision(5) << liquidComposition << " " -//<< std::fixed << std::setprecision(5) << vapourComposition << " " -<< std::scientific << std::setprecision(5) << residual << " " -<< "\n"; } // Test if we have converged to a null or trivial solution diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp index 64a0d0ce7f3..8dcbb2f529f 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp @@ -39,7 +39,7 @@ FlashParameters::FlashParameters( std::unique_ptr< ModelParameters > parameters m_continuousParameters[STABILITY_THRESHOLD] = -1.0e-8; m_continuousParameters[STABILITY_TOLERANCE] = 1.0e-8; m_continuousParameters[FLASH_TOLERANCE] = 1.0e-8; - m_continuousParameters[NEGATIVE_FLASH_TOLERANCE] = -1.0e-1; + m_continuousParameters[NEGATIVE_FLASH_TOLERANCE] = 1.0e-5; m_continuousParameters[SSI_TOLERANCE] = 1.0e-3; m_discreteParameters[STABILITY_MAX_ITERATIONS] = 300; @@ -87,6 +87,12 @@ void FlashParameters::registerParametersImpl( MultiFluidBase * fluid ) setInputFlag( dataRepository::InputFlags::OPTIONAL ). setDefaultValue( m_continuousParameters[SSI_TOLERANCE] ). setDescription( "The tolerance to use to switch from SSI iterations to Newton iterations" ); + + fluid->registerWrapper( viewKeyStruct::negativeFlashToleranceString(), &m_continuousParameters[NEGATIVE_FLASH_TOLERANCE] ). + setInputFlag( dataRepository::InputFlags::OPTIONAL ). + setDefaultValue( m_continuousParameters[NEGATIVE_FLASH_TOLERANCE] ). + setDescription( "The tolerance within the physical region [0,1] which the phase fraction must be in " + "order to allow a switch from SSI iterations to Newton iterations" ); } void FlashParameters::postInputInitializationImpl( MultiFluidBase const * fluid, diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp index 747d79b38fb..3e225e6508b 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.hpp @@ -83,6 +83,7 @@ class FlashParameters : public ModelParameters static constexpr char const * stabilityToleranceString() { return "stabilityTolerance"; } static constexpr char const * ssiToleranceString() { return "ssiTolerance"; } static constexpr char const * stabilityMaxIterationsString() { return "stabilityMaxIterations"; } + static constexpr char const * negativeFlashToleranceString() { return "negativeFlashTolerance"; } }; array1d< real64 > m_continuousParameters; diff --git a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp index 664c40e5025..80aae8c1932 100644 --- a/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp +++ b/src/coreComponents/constitutive/unitTests/TestFluidUtilities.hpp @@ -108,24 +108,10 @@ void testNumericalDerivative( real64 const x, selectedDerivative = deriv; } } - // checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, - // GEOS_FMT( "Numerical derivative for component {}", i ) ); - ((void)relTolerance); - ((void)absTolerance); - real64 const maxV = 1.0e-14 + LvArray::math::max( LvArray::math::abs( selectedDerivative ), LvArray::math::abs( derivatives[i] )); - std::cout - << std::setw( 2 ) << i << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << selectedDerivative << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << derivatives[i] << " | " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << leftValues[i] << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << centreValues[i] << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << rightValues[i] << " | " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << selectedDerivative - derivatives[i] << " " - << std::scientific << std::setprecision( 5 ) << std::setw( 12 ) << (selectedDerivative - derivatives[i])/maxV << " " - << "\n"; - } - std::cout << "----------------------------------------------------------\n"; + checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, + GEOS_FMT( "Numerical derivative for component {}", i ) ); } +} /** * @brief Tests a multi-valued function against a second derivative @@ -142,53 +128,53 @@ void testNumericalDerivative( real64 const x, * @param absTolerance The absolute tolerance to use for the comparison * @param relTolerance The relative tolerance to use for the comparison */ - template< integer numValues, typename FUNCTION > - void testNumericalSecondDerivative( real64 const x, - real64 const dx, - arraySlice1d< real64 const > const & derivatives, - FUNCTION && function, - real64 const absTolerance = absTol, - real64 const relTolerance = relTol ) +template< integer numValues, typename FUNCTION > +void testNumericalSecondDerivative( real64 const x, + real64 const dx, + arraySlice1d< real64 const > const & derivatives, + FUNCTION && function, + real64 const absTolerance = absTol, + real64 const relTolerance = relTol ) +{ + stackArray2d< real64, 5*numValues > values( 5, numValues ); + function( x-2.0*dx, values[0] ); + function( x-dx, values[1] ); + function( x, values[2] ); + function( x+dx, values[3] ); + function( x+2.0*dx, values[4] ); + + real64 constexpr stencils[6][5] = { + {1.0, -2.0, 1.0, 0.0, 0.0}, + {-1.0, 4.0, -5.0, 2.0, 0.0}, + {-1.0/12.0, 16.0/12.0, -30.0/12.0, 16.0/12.0, -1.0/12.0}, + {0.0, 1.0, -2.0, 1.0, 0.0}, + {0.0, -1.0, 4.0, -5.0, 2.0}, + {0.0, 0.0, 1.0, -2.0, 1.0}, + }; + real64 const invdx2 = 1.0 / (dx*dx); + for( integer i = 0; i < numValues; ++i ) { - stackArray2d< real64, 5*numValues > values( 5, numValues ); - function( x-2.0*dx, values[0] ); - function( x-dx, values[1] ); - function( x, values[2] ); - function( x+dx, values[3] ); - function( x+2.0*dx, values[4] ); - - real64 constexpr stencils[6][5] = { - {1.0, -2.0, 1.0, 0.0, 0.0}, - {-1.0, 4.0, -5.0, 2.0, 0.0}, - {-1.0/12.0, 16.0/12.0, -30.0/12.0, 16.0/12.0, -1.0/12.0}, - {0.0, 1.0, -2.0, 1.0, 0.0}, - {0.0, -1.0, 4.0, -5.0, 2.0}, - {0.0, 0.0, 1.0, -2.0, 1.0}, - }; - real64 const invdx2 = 1.0 / (dx*dx); - for( integer i = 0; i < numValues; ++i ) + real64 minError = LvArray::NumericLimits< real64 >::max; + real64 selectedDerivative = 0.0; + for( integer si = 0; si < 6; si++ ) { - real64 minError = LvArray::NumericLimits< real64 >::max; - real64 selectedDerivative = 0.0; - for( integer si = 0; si < 6; si++ ) + real64 deriv = 0.0; + for( integer ci = 0; ci < 5; ci++ ) { - real64 deriv = 0.0; - for( integer ci = 0; ci < 5; ci++ ) - { - deriv += stencils[si][ci]*values( ci, i ); - } - deriv *= invdx2; - real64 const error = LvArray::math::abs( deriv - derivatives[i] ); - if( error < minError ) - { - minError = error; - selectedDerivative = deriv; - } + deriv += stencils[si][ci]*values( ci, i ); + } + deriv *= invdx2; + real64 const error = LvArray::math::abs( deriv - derivatives[i] ); + if( error < minError ) + { + minError = error; + selectedDerivative = deriv; } - checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, - GEOS_FMT( "Numerical derivative for component {}", i ) ); } + checkRelativeError( derivatives[i], selectedDerivative, relTolerance, absTolerance, + GEOS_FMT( "Numerical derivative for component {}", i ) ); } +} }// namespace internal diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp index df795bff03c..48b350819bf 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlash9Comp.cpp @@ -90,8 +90,7 @@ class NegativeTwoPhaseFlashTest9CompFixture : public ::testing::TestWithParam< auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); auto const * flashParameters = parameters->get< FlashParameters >(); - flashParameters->m_discreteParameters[FlashParameters::FLASH_MAX_ITERATIONS] = 20; - //flashParameters->m_continuousParameters[FlashParameters::SSI_TOLERANCE] = 1.0e-6; + flashParameters->m_discreteParameters[FlashParameters::FLASH_MAX_ITERATIONS] = 100; bool status = NegativeTwoPhaseFlash::compute( numComps, @@ -307,13 +306,13 @@ std::unique_ptr< TestFluid< numComps > > NegativeTwoPhaseFlashTest9CompFixture< } using PengRobinson = NegativeTwoPhaseFlashTest9CompFixture< EquationOfStateType::PengRobinson >; -//using SoaveRedlichKwong = NegativeTwoPhaseFlashTest9CompFixture< EquationOfStateType::SoaveRedlichKwong >; +using SoaveRedlichKwong = NegativeTwoPhaseFlashTest9CompFixture< EquationOfStateType::SoaveRedlichKwong >; TEST_P( PengRobinson, testNegativeFlash ) { testFlash( GetParam() ); } -/* + TEST_P( PengRobinson, testNegativeFlashDerivatives ) { testFlashDerivatives( GetParam() ); @@ -328,7 +327,7 @@ TEST_P( SoaveRedlichKwong, testNegativeFlashDerivatives ) { testFlashDerivatives( GetParam() ); } -*/ + //------------------------------------------------------------------------------- // Data //------------------------------------------------------------------------------- @@ -338,131 +337,131 @@ TEST_P( SoaveRedlichKwong, testNegativeFlashDerivatives ) INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlash, PengRobinson, ::testing::Values( - //FlashData( 1.000000e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+05, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.798353, {0.000363, 0.839010}, {0.011181, 0.000020} ), - //FlashData( 1.000000e+05, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998685, {0.000228, 0.938644}, {0.007035, 0.000022} ), - //FlashData( 1.013250e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.013250e+05, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.798070, {0.000368, 0.837836}, {0.011184, 0.000020} ), - FlashData( 1.013250e+05, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998684, {0.000231, 0.937856}, {0.007035, 0.000022} ) - //FlashData( 1.000000e+06, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ) - //FlashData( 1.000000e+06, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.700780, {0.003486, 0.565464}, {0.011355, 0.000003} ), - //FlashData( 1.000000e+06, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.997643, {0.002159, 0.531971}, {0.007037, 0.000002} ), - //FlashData( 1.000000e+07, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ) - //FlashData( 1.000000e+07, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.349114, {0.010010, 0.259905}, {0.007116, 0.000090} ), - //FlashData( 1.000000e+07, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.991703, {0.009755, 0.140969}, {0.007003, 0.000087} ), - //FlashData( 1.500000e+07, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.500000e+07, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.176058, {0.009422, 0.205086}, {0.007026, 0.001256} ), - //FlashData( 1.500000e+07, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.009422, 0.205089}, {0.007026, 0.001256} ), - //FlashData( 5.000000e+07, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+08, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.000000e+05, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.001168, {0.000348, 0.839991}, {0.013059, 0.000053} ), - //FlashData( 1.000000e+05, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.805671, {0.000295, 0.870461}, {0.011100, 0.000055} ), - //FlashData( 1.000000e+05, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998750, {0.000187, 0.957531}, {0.007035, 0.000059} ), - //FlashData( 1.013250e+05, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.001057, {0.000350, 0.839898}, {0.012947, 0.000052} ), - //FlashData( 1.013250e+05, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.805431, {0.000299, 0.869390}, {0.011102, 0.000054} ), - //FlashData( 1.013250e+05, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998749, {0.000189, 0.956982}, {0.007035, 0.000058} ), - //FlashData( 1.000000e+06, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+06, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.719045, {0.002880, 0.602213}, {0.011391, 0.000007} ), - //FlashData( 1.000000e+06, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998097, {0.001770, 0.656139}, {0.007036, 0.000007} ), - //FlashData( 1.000000e+07, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+07, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.391974, {0.009806, 0.278198}, {0.007750, 0.000123} ), - //FlashData( 1.000000e+07, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.994318, {0.008887, 0.201207}, {0.007015, 0.000113} ), - //FlashData( 1.500000e+07, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.500000e+07, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.231493, {0.009474, 0.219807}, {0.007427, 0.001195} ), - //FlashData( 1.500000e+07, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999406, {0.009004, 0.228228}, {0.007025, 0.001121} ), - //FlashData( 5.000000e+07, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+05, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.002535, {0.000327, 0.841142}, {0.014448, 0.000119} ), - //FlashData( 1.000000e+05, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.811028, {0.000249, 0.894832}, {0.011039, 0.000125} ), - //FlashData( 1.000000e+05, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998841, {0.000158, 0.968326}, {0.007034, 0.000134} ), - //FlashData( 1.013250e+05, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.002401, {0.000329, 0.841029}, {0.014353, 0.000118} ), - //FlashData( 1.013250e+05, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.810823, {0.000253, 0.893869}, {0.011041, 0.000124} ), - //FlashData( 1.013250e+05, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998839, {0.000161, 0.967914}, {0.007034, 0.000132} ), - //FlashData( 1.000000e+06, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+06, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.733594, {0.002451, 0.635078}, {0.011378, 0.000016} ), - //FlashData( 1.000000e+06, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998313, {0.001505, 0.734457}, {0.007035, 0.000017} ), - //FlashData( 1.000000e+07, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+07, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.426139, {0.009539, 0.294719}, {0.008274, 0.000169} ), - //FlashData( 1.000000e+07, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.995698, {0.008127, 0.256601}, {0.007021, 0.000153} ), - //FlashData( 1.500000e+07, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.500000e+07, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.275063, {0.009454, 0.232929}, {0.007803, 0.001242} ), - //FlashData( 1.500000e+07, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999403, {0.008577, 0.252667}, {0.007025, 0.001106} ), - //FlashData( 5.000000e+07, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+05, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.009514, {0.000227, 0.847062}, {0.014475, 0.000776} ), - //FlashData( 1.000000e+05, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.820830, {0.000171, 0.940506}, {0.010927, 0.000840} ), - //FlashData( 1.000000e+05, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999605, {0.000110, 0.982954}, {0.007029, 0.000869} ), - //FlashData( 1.013250e+05, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.009213, {0.000231, 0.846804}, {0.014528, 0.000766} ), - //FlashData( 1.013250e+05, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.820694, {0.000173, 0.939845}, {0.010929, 0.000829} ), - //FlashData( 1.013250e+05, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999594, {0.000111, 0.982731}, {0.007029, 0.000858} ), - //FlashData( 1.000000e+06, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+06, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.763803, {0.001692, 0.716010}, {0.011260, 0.000105} ), - //FlashData( 1.000000e+06, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998655, {0.001048, 0.848573}, {0.007034, 0.000115} ), - //FlashData( 1.000000e+07, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+07, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.500392, {0.008630, 0.338259}, {0.009369, 0.000406} ), - //FlashData( 1.000000e+07, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.997667, {0.006476, 0.384497}, {0.007027, 0.000360} ), - //FlashData( 1.500000e+07, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.500000e+07, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.367748, {0.009160, 0.266615}, {0.008725, 0.001720} ), - //FlashData( 1.500000e+07, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 5.000000e+07, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+05, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.031155, {0.000097, 0.865831}, {0.008647, 0.004929} ), - //FlashData( 1.000000e+05, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.829852, {0.000120, 0.968392}, {0.010821, 0.005338} ), - //FlashData( 1.000000e+05, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.013250e+05, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.030488, {0.000099, 0.865241}, {0.008755, 0.004866} ), - //FlashData( 1.013250e+05, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.829724, {0.000121, 0.968002}, {0.010822, 0.005269} ), - //FlashData( 1.013250e+05, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.000000e+06, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+06, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.787992, {0.001191, 0.795638}, {0.011101, 0.000658} ), - //FlashData( 1.000000e+06, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999382, {0.000748, 0.906103}, {0.007030, 0.000696} ), - //FlashData( 1.000000e+07, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+07, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.567463, {0.007479, 0.389712}, {0.010159, 0.001120} ), - //FlashData( 1.000000e+07, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999429, {0.005131, 0.493383}, {0.007027, 0.000975} ), - //FlashData( 1.500000e+07, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.500000e+07, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.449715, {0.008545, 0.304966}, {0.009556, 0.003072} ), - //FlashData( 1.500000e+07, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.000000e+05, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.053370, {0.000054, 0.885524}, {0.005836, 0.013991} ), - //FlashData( 1.000000e+05, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.839835, {0.000099, 0.977972}, {0.010698, 0.014959} ), - //FlashData( 1.000000e+05, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.013250e+05, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.052543, {0.000056, 0.884773}, {0.005903, 0.013808} ), - //FlashData( 1.013250e+05, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.839621, {0.000100, 0.977689}, {0.010700, 0.014767} ), - //FlashData( 1.013250e+05, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.000000e+06, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+06, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.799362, {0.000988, 0.836026}, {0.011011, 0.001828} ), - //FlashData( 1.000000e+06, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.000000e+07, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+07, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.602229, {0.006805, 0.422215}, {0.010450, 0.002084} ), - //FlashData( 1.000000e+07, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.500000e+07, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.500000e+07, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.492074, {0.008098, 0.328602}, {0.009931, 0.004663} ), - //FlashData( 1.500000e+07, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.000000e+05, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.078426, {0.000034, 0.907428}, {0.004230, 0.035040} ), - //FlashData( 1.000000e+05, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.860286, {0.000083, 0.983960}, {0.010448, 0.036880} ), - //FlashData( 1.000000e+05, 3.931500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.013250e+05, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.077531, {0.000035, 0.906620}, {0.004269, 0.034580} ), - //FlashData( 1.013250e+05, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.859825, {0.000084, 0.983745}, {0.010454, 0.036407} ), - //FlashData( 1.000000e+06, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+06, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.808966, {0.000846, 0.866838}, {0.010926, 0.004456} ), - //FlashData( 1.000000e+07, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.630979, {0.006236, 0.452193}, {0.010617, 0.003695} ), - //FlashData( 1.500000e+07, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.527277, {0.007678, 0.350047}, {0.010185, 0.007065} ), - //FlashData( 1.500000e+07, 3.931500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 5.000000e+07, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.013250e+05, 5.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.000000e+06, 5.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.013401, {0.000295, 0.847670}, {0.005333, 0.201455} ), - //FlashData( 1.000000e+06, 5.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), - //FlashData( 1.000000e+07, 5.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+07, 5.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.783614, {0.004654, 0.554668}, {0.010200, 0.062757} ), - //FlashData( 1.500000e+07, 5.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.500000e+07, 5.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.717160, {0.006496, 0.400841}, {0.009988, 0.077843} ), - //FlashData( 1.013250e+05, 5.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.000000e+06, 5.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.166124, {0.000103, 0.906268}, {0.001666, 0.501402} ), - //FlashData( 1.000000e+07, 5.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.947056, {0.004797, 0.541766}, {0.009235, 0.148372} ), - //FlashData( 8.000000e+07, 8.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 8.000000e+07, 8.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), - //FlashData( 8.000000e+07, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), - //FlashData( 1.000000e+08, 8.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), - //FlashData( 1.000000e+08, 8.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), - //FlashData( 1.000000e+08, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ) + FlashData( 1.000000e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+05, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.798353, {0.000363, 0.839010}, {0.011181, 0.000020} ), + FlashData( 1.000000e+05, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998685, {0.000228, 0.938644}, {0.007035, 0.000022} ), + FlashData( 1.013250e+05, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.013250e+05, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.798070, {0.000368, 0.837836}, {0.011184, 0.000020} ), + FlashData( 1.013250e+05, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998684, {0.000231, 0.937856}, {0.007035, 0.000022} ), + FlashData( 1.000000e+06, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+06, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.700780, {0.003486, 0.565464}, {0.011355, 0.000003} ), + FlashData( 1.000000e+06, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.997643, {0.002159, 0.531971}, {0.007037, 0.000002} ), + FlashData( 1.000000e+07, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+07, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.349114, {0.010010, 0.259905}, {0.007116, 0.000090} ), + FlashData( 1.000000e+07, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.991703, {0.009755, 0.140969}, {0.007003, 0.000087} ), + FlashData( 1.500000e+07, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.500000e+07, 2.781500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.176058, {0.009422, 0.205086}, {0.007026, 0.001256} ), + FlashData( 1.500000e+07, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.009422, 0.205089}, {0.007026, 0.001256} ), + FlashData( 5.000000e+07, 2.781500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+08, 2.781500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.000000e+05, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.001168, {0.000348, 0.839991}, {0.013059, 0.000053} ), + FlashData( 1.000000e+05, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.805671, {0.000295, 0.870461}, {0.011100, 0.000055} ), + FlashData( 1.000000e+05, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998750, {0.000187, 0.957531}, {0.007035, 0.000059} ), + FlashData( 1.013250e+05, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.001057, {0.000350, 0.839898}, {0.012947, 0.000052} ), + FlashData( 1.013250e+05, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.805431, {0.000299, 0.869390}, {0.011102, 0.000054} ), + FlashData( 1.013250e+05, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998749, {0.000189, 0.956982}, {0.007035, 0.000058} ), + FlashData( 1.000000e+06, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+06, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.719045, {0.002880, 0.602213}, {0.011391, 0.000007} ), + FlashData( 1.000000e+06, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998097, {0.001770, 0.656139}, {0.007036, 0.000007} ), + FlashData( 1.000000e+07, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+07, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.391974, {0.009806, 0.278198}, {0.007750, 0.000123} ), + FlashData( 1.000000e+07, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.994318, {0.008887, 0.201207}, {0.007015, 0.000113} ), + FlashData( 1.500000e+07, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.500000e+07, 2.886500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.231493, {0.009474, 0.219807}, {0.007427, 0.001195} ), + FlashData( 1.500000e+07, 2.886500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999406, {0.009004, 0.228228}, {0.007025, 0.001121} ), + FlashData( 5.000000e+07, 2.886500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+05, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.002535, {0.000327, 0.841142}, {0.014448, 0.000119} ), + FlashData( 1.000000e+05, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.811028, {0.000249, 0.894832}, {0.011039, 0.000125} ), + FlashData( 1.000000e+05, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998841, {0.000158, 0.968326}, {0.007034, 0.000134} ), + FlashData( 1.013250e+05, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.002401, {0.000329, 0.841029}, {0.014353, 0.000118} ), + FlashData( 1.013250e+05, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.810823, {0.000253, 0.893869}, {0.011041, 0.000124} ), + FlashData( 1.013250e+05, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998839, {0.000161, 0.967914}, {0.007034, 0.000132} ), + FlashData( 1.000000e+06, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+06, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.733594, {0.002451, 0.635078}, {0.011378, 0.000016} ), + FlashData( 1.000000e+06, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998313, {0.001505, 0.734457}, {0.007035, 0.000017} ), + FlashData( 1.000000e+07, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+07, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.426139, {0.009539, 0.294719}, {0.008274, 0.000169} ), + FlashData( 1.000000e+07, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.995698, {0.008127, 0.256601}, {0.007021, 0.000153} ), + FlashData( 1.500000e+07, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.500000e+07, 2.981500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.275063, {0.009454, 0.232929}, {0.007803, 0.001242} ), + FlashData( 1.500000e+07, 2.981500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999403, {0.008577, 0.252667}, {0.007025, 0.001106} ), + FlashData( 5.000000e+07, 2.981500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+05, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.009514, {0.000227, 0.847062}, {0.014475, 0.000776} ), + FlashData( 1.000000e+05, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.820830, {0.000171, 0.940506}, {0.010927, 0.000840} ), + FlashData( 1.000000e+05, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999605, {0.000110, 0.982954}, {0.007029, 0.000869} ), + FlashData( 1.013250e+05, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.009213, {0.000231, 0.846804}, {0.014528, 0.000766} ), + FlashData( 1.013250e+05, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.820694, {0.000173, 0.939845}, {0.010929, 0.000829} ), + FlashData( 1.013250e+05, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999594, {0.000111, 0.982731}, {0.007029, 0.000858} ), + FlashData( 1.000000e+06, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+06, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.763803, {0.001692, 0.716010}, {0.011260, 0.000105} ), + FlashData( 1.000000e+06, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.998655, {0.001048, 0.848573}, {0.007034, 0.000115} ), + FlashData( 1.000000e+07, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+07, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.500392, {0.008630, 0.338259}, {0.009369, 0.000406} ), + FlashData( 1.000000e+07, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.997667, {0.006476, 0.384497}, {0.007027, 0.000360} ), + FlashData( 1.500000e+07, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.500000e+07, 3.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.367748, {0.009160, 0.266615}, {0.008725, 0.001720} ), + FlashData( 1.500000e+07, 3.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 5.000000e+07, 3.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+05, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.031155, {0.000097, 0.865831}, {0.008647, 0.004929} ), + FlashData( 1.000000e+05, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.829852, {0.000120, 0.968392}, {0.010821, 0.005338} ), + FlashData( 1.000000e+05, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.013250e+05, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.030488, {0.000099, 0.865241}, {0.008755, 0.004866} ), + FlashData( 1.013250e+05, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.829724, {0.000121, 0.968002}, {0.010822, 0.005269} ), + FlashData( 1.013250e+05, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.000000e+06, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+06, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.787992, {0.001191, 0.795638}, {0.011101, 0.000658} ), + FlashData( 1.000000e+06, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999382, {0.000748, 0.906103}, {0.007030, 0.000696} ), + FlashData( 1.000000e+07, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+07, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.567463, {0.007479, 0.389712}, {0.010159, 0.001120} ), + FlashData( 1.000000e+07, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 0.999429, {0.005131, 0.493383}, {0.007027, 0.000975} ), + FlashData( 1.500000e+07, 3.531500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.500000e+07, 3.531500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.449715, {0.008545, 0.304966}, {0.009556, 0.003072} ), + FlashData( 1.500000e+07, 3.531500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.000000e+05, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.053370, {0.000054, 0.885524}, {0.005836, 0.013991} ), + FlashData( 1.000000e+05, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.839835, {0.000099, 0.977972}, {0.010698, 0.014959} ), + FlashData( 1.000000e+05, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.013250e+05, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.052543, {0.000056, 0.884773}, {0.005903, 0.013808} ), + FlashData( 1.013250e+05, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.839621, {0.000100, 0.977689}, {0.010700, 0.014767} ), + FlashData( 1.013250e+05, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.000000e+06, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+06, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.799362, {0.000988, 0.836026}, {0.011011, 0.001828} ), + FlashData( 1.000000e+06, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.000000e+07, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+07, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.602229, {0.006805, 0.422215}, {0.010450, 0.002084} ), + FlashData( 1.000000e+07, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.500000e+07, 3.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.500000e+07, 3.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.492074, {0.008098, 0.328602}, {0.009931, 0.004663} ), + FlashData( 1.500000e+07, 3.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.000000e+05, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.078426, {0.000034, 0.907428}, {0.004230, 0.035040} ), + FlashData( 1.000000e+05, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.860286, {0.000083, 0.983960}, {0.010448, 0.036880} ), + FlashData( 1.000000e+05, 3.931500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.013250e+05, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.077531, {0.000035, 0.906620}, {0.004269, 0.034580} ), + FlashData( 1.013250e+05, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.859825, {0.000084, 0.983745}, {0.010454, 0.036407} ), + FlashData( 1.000000e+06, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+06, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.808966, {0.000846, 0.866838}, {0.010926, 0.004456} ), + FlashData( 1.000000e+07, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.630979, {0.006236, 0.452193}, {0.010617, 0.003695} ), + FlashData( 1.500000e+07, 3.931500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.527277, {0.007678, 0.350047}, {0.010185, 0.007065} ), + FlashData( 1.500000e+07, 3.931500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 5.000000e+07, 3.931500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.013250e+05, 5.231500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.000000e+06, 5.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.013401, {0.000295, 0.847670}, {0.005333, 0.201455} ), + FlashData( 1.000000e+06, 5.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), + FlashData( 1.000000e+07, 5.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+07, 5.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.783614, {0.004654, 0.554668}, {0.010200, 0.062757} ), + FlashData( 1.500000e+07, 5.231500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.500000e+07, 5.231500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.717160, {0.006496, 0.400841}, {0.009988, 0.077843} ), + FlashData( 1.013250e+05, 5.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.000000e+06, 5.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.166124, {0.000103, 0.906268}, {0.001666, 0.501402} ), + FlashData( 1.000000e+07, 5.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 0.947056, {0.004797, 0.541766}, {0.009235, 0.148372} ), + FlashData( 8.000000e+07, 8.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 8.000000e+07, 8.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), + FlashData( 8.000000e+07, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ), + FlashData( 1.000000e+08, 8.731500e+02, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 1, 0.000000, {0.000363, 0.839010}, {0.000363, 0.839010} ), + FlashData( 1.000000e+08, 8.731500e+02, {0.009000, 0.003000, 0.534700, 0.114600, 0.087900, 0.045600, 0.020900, 0.015100, 0.169200}, 1, 1.000000, {0.009000, 0.169200}, {0.009000, 0.169200} ), + FlashData( 1.000000e+08, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ) ) ); -/* + INSTANTIATE_TEST_SUITE_P( NegativeTwoPhaseFlash, SoaveRedlichKwong, ::testing::Values( @@ -573,7 +572,7 @@ INSTANTIATE_TEST_SUITE_P( FlashData( 1.000000e+08, 8.731500e+02, {0.007026, 0.006161, 0.827761, 0.091046, 0.045353, 0.015026, 0.004474, 0.001898, 0.001256}, 1, 1.000000, {0.007026, 0.001256}, {0.007026, 0.001256} ) ) ); -*/ + /* UNCRUSTIFY-ON */ } // testing diff --git a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashJacobian.cpp b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashJacobian.cpp index cd7572442eb..b4d52b40319 100644 --- a/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashJacobian.cpp +++ b/src/coreComponents/constitutive/unitTests/testNegativeTwoPhaseFlashJacobian.cpp @@ -53,28 +53,28 @@ struct FluidData< 4 > template<> struct FluidData< 9 > { -static std::unique_ptr< TestFluid< 9 > > createFluid() -{ - std::unique_ptr< TestFluid< 9 > > fluid = TestFluid< 9 >::create( {0, 0, 0, 0, 0, 0, 0, 0, 0} ); - // Manually populate - TestFluid< 9 >::populateArray( fluid->criticalPressure, Feed< 9 >{73.8659e5, 33.9439e5, 46.0421e5, 48.8387e5, 42.4552e5, 37.47e5, 33.5892e5, 30.1037e5, 20.549e5} ); - TestFluid< 9 >::populateArray( fluid->criticalTemperature, Feed< 9 >{304.7, 126.2, 190.6, 305.43, 369.8, 419.5, 465.9, 507.5, 678.8} ); - TestFluid< 9 >::populateArray( fluid->criticalVolume, Feed< 9 >{9.3999e-05, 9.0001e-05, 9.7999e-05, 1.4800e-04, 2.0000e-04, 2.5800e-04, 3.1000e-04, 3.5100e-04, 6.8243e-04} ); - TestFluid< 9 >::populateArray( fluid->acentricFactor, Feed< 9 >{0.225, 0.04, 0.013, 0.0986, 0.1524, 0.1956, 0.2413, 0.299, 0.5618} ); - TestFluid< 9 >::populateArray( fluid->molecularWeight, Feed< 9 >{44.01e-3, 28.01e-3, 16.04e-3, 30.07e-3, 44.1e-3, 58.12e-3, 72.15e-3, 84e-3, 173e-3} ); - TestFluid< 9 >::populateArray( fluid->volumeShift, Feed< 9 >{ -0.04958, -0.136012, -0.1486264, -0.10863408, -0.08349872, -0.06331568, -0.04196464, -0.0150072, 0.0000 } ); - fluid->setBinaryCoefficients( Feed< 36 >{ - 1.0000e-02, - 0.0000e+00, 3.7320e-03, - 0.0000e+00, 1.0000e-02, 0.0000e+00, - 0.0000e+00, 1.0000e-02, 0.0000e+00, 0.0000e+00, - 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, - 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, - 1.0000e-02, 0.0000e+00, 2.8000e-02, 1.0000e-02, 1.0000e-02, 0.0000e+00, 0.0000e+00, - 1.0000e-02, 0.0000e+00, 4.5320e-02, 1.0000e-02, 1.0000e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00 - } ); - return fluid; -} + static std::unique_ptr< TestFluid< 9 > > createFluid() + { + std::unique_ptr< TestFluid< 9 > > fluid = TestFluid< 9 >::create( {0, 0, 0, 0, 0, 0, 0, 0, 0} ); + // Manually populate + TestFluid< 9 >::populateArray( fluid->criticalPressure, Feed< 9 >{73.8659e5, 33.9439e5, 46.0421e5, 48.8387e5, 42.4552e5, 37.47e5, 33.5892e5, 30.1037e5, 20.549e5} ); + TestFluid< 9 >::populateArray( fluid->criticalTemperature, Feed< 9 >{304.7, 126.2, 190.6, 305.43, 369.8, 419.5, 465.9, 507.5, 678.8} ); + TestFluid< 9 >::populateArray( fluid->criticalVolume, Feed< 9 >{9.3999e-05, 9.0001e-05, 9.7999e-05, 1.4800e-04, 2.0000e-04, 2.5800e-04, 3.1000e-04, 3.5100e-04, 6.8243e-04} ); + TestFluid< 9 >::populateArray( fluid->acentricFactor, Feed< 9 >{0.225, 0.04, 0.013, 0.0986, 0.1524, 0.1956, 0.2413, 0.299, 0.5618} ); + TestFluid< 9 >::populateArray( fluid->molecularWeight, Feed< 9 >{44.01e-3, 28.01e-3, 16.04e-3, 30.07e-3, 44.1e-3, 58.12e-3, 72.15e-3, 84e-3, 173e-3} ); + TestFluid< 9 >::populateArray( fluid->volumeShift, Feed< 9 >{ -0.04958, -0.136012, -0.1486264, -0.10863408, -0.08349872, -0.06331568, -0.04196464, -0.0150072, 0.0000 } ); + fluid->setBinaryCoefficients( Feed< 36 >{ + 1.0000e-02, + 0.0000e+00, 3.7320e-03, + 0.0000e+00, 1.0000e-02, 0.0000e+00, + 0.0000e+00, 1.0000e-02, 0.0000e+00, 0.0000e+00, + 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, + 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, + 1.0000e-02, 0.0000e+00, 2.8000e-02, 1.0000e-02, 1.0000e-02, 0.0000e+00, 0.0000e+00, + 1.0000e-02, 0.0000e+00, 4.5320e-02, 1.0000e-02, 1.0000e-02, 0.0000e+00, 0.0000e+00, 0.0000e+00 + } ); + return fluid; + } }; template< int NC > @@ -148,13 +148,6 @@ class NegativeTwoPhaseFlashJacobianTestFixture : public ::testing::TestWithPara componentProperties, kValues ); - std::array kv{ 5.50659394e-01, 6.30017745e+00, 2.74421602e+00, 4.80354013e-01, 1.56281500e-01, 5.21905616e-02, 1.78835233e-02, 5.75547635e-03, 9.74533928e-06 }; - for( integer ic = 0; ic < numComps; ++ic ) - { - kValues[ic] = kv[ic]; - } - - NegativeTwoPhaseFlash::calculateResidualAndJacobian( numComps, pressure, temperature, @@ -171,15 +164,7 @@ class NegativeTwoPhaseFlashJacobianTestFixture : public ::testing::TestWithPara logVapourFugacityDerivs, residual, jacobian ); - - std::cout << "RESIDUAL " << std::scientific << std::setprecision( 5 ) << residual << "\n"; - std::cout << "JACOBIAN\n"; - for( integer kc = 0; kc <= numComps; ++kc ) - { - std::cout << " " << jacobian[kc] << "\n"; - } - std::cout << "=============================================\n"; - + // k-value derivatives // Derivatives are wrt to log(K) real64 constexpr deltaLogK = 1.0e-3; @@ -214,7 +199,7 @@ class NegativeTwoPhaseFlashJacobianTestFixture : public ::testing::TestWithPara } // Vapour fraction derivative - real64 constexpr deltaV = 1.0e-5; + real64 constexpr deltaV = 1.0e-7; extractColumn( numComps ); geos::testing::internal::testNumericalDerivative< numValues >( 0.0, deltaV, derivatives, @@ -245,20 +230,21 @@ class NegativeTwoPhaseFlashJacobianTestFixture : public ::testing::TestWithPara }; //using PengRobinson4 = NegativeTwoPhaseFlashJacobianTestFixture< 4, EquationOfStateType::PengRobinson, EquationOfStateType::PengRobinson >; -//using SoreideWhitson4 = NegativeTwoPhaseFlashJacobianTestFixture< 4, EquationOfStateType::SoreideWhitson, EquationOfStateType::PengRobinson >; +//using SoreideWhitson4 = NegativeTwoPhaseFlashJacobianTestFixture< 4, EquationOfStateType::SoreideWhitson, +// EquationOfStateType::PengRobinson >; using PengRobinson9 = NegativeTwoPhaseFlashJacobianTestFixture< 9, EquationOfStateType::PengRobinson, EquationOfStateType::PengRobinson >; /* -TEST_P( PengRobinson4, testJacobian ) -{ - testJacobian( GetParam() ); -} - -TEST_P( SoreideWhitson4, testJacobian ) -{ - testJacobian( GetParam() ); -} -*/ + TEST_P( PengRobinson4, testJacobian ) + { + testJacobian( GetParam() ); + } + + TEST_P( SoreideWhitson4, testJacobian ) + { + testJacobian( GetParam() ); + } + */ TEST_P( PengRobinson9, testJacobian ) { testJacobian( GetParam() ); @@ -290,7 +276,9 @@ INSTANTIATE_TEST_SUITE_P(NegativeTwoPhaseFlashJacobian, SoreideWhitson4, INSTANTIATE_TEST_SUITE_P(NegativeTwoPhaseFlashJacobian, PengRobinson9, ::testing::ValuesIn>({ - {1.00000e+07, 278.15, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, -0.18866442} + //{1.00000e+07, 278.15, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, -0.18866442} + //{1.00000e+07, 278.15, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, 0.18866442} + {1.00000e+07, 278.15, {0.000363, 0.000007, 0.003471, 0.006007, 0.018423, 0.034034, 0.042565, 0.056120, 0.839010}, -0.01} }) ); From ee9f5292b22da670ce136465b7814ad23b6ead15 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Thu, 5 Nov 2026 17:50:10 +0100 Subject: [PATCH 28/28] Update stability test --- .../functions/StabilityTest_impl.hpp | 98 +++-- .../compositional/functions/Utilities.hpp | 71 ++-- .../parameters/FlashParameters.cpp | 21 +- .../constitutive/unitTests/CMakeLists.txt | 1 + .../unitTests/testStabilityTest2Comp.cpp | 1 + .../unitTests/testStabilityTest9Comp.cpp | 165 ++++++-- .../testStabilityTestDerivatives.cpp | 372 ++++++++++++++++++ .../unitTests/testStabilityTestJacobian.cpp | 153 ++++--- 8 files changed, 749 insertions(+), 133 deletions(-) create mode 100644 src/coreComponents/constitutive/unitTests/testStabilityTestDerivatives.cpp diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp index 014c0d85512..f74bf07d254 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/StabilityTest_impl.hpp @@ -72,8 +72,6 @@ bool StabilityTest::compute( integer const numComps, real64 const stabilityTolerance = continuousFlashParameters[FlashParameters::STABILITY_TOLERANCE]; real64 const stabilitySSITolerance = continuousFlashParameters[FlashParameters::SSI_TOLERANCE]; - integer const numConfigSteps = flashData.liquidEos == flashData.vapourEos ? 1 : 2; - // Initialise by assuming a stable mixture unstableMixture = false; @@ -81,12 +79,23 @@ bool StabilityTest::compute( integer const numComps, bool allConverged = true; // Measure of distance to trivial solution - real64 maxDistanceToTrivialSolution = 0.0; + real64 maxDistanceToTrivialSolution = -LvArray::NumericLimits< real64 >::max; + auto const storeIncipientComposition = [&]( EquationOfStateType const eos ) + { + incipientEquationOfState = eos; + for( integer ic = 0; ic < numComps; ++ic ) + { + incipientComposition[ic] = testComposition[ic]; + } + }; + + // If the 2 EOS are not the same, we will do 2 passes swapping the 2 EOS if required + integer const numConfigSteps = flashData.liquidEos == flashData.vapourEos ? 1 : 2; for( integer configStep = 0; configStep < numConfigSteps; ++configStep ) { EquationOfStateType const sampleEos = (configStep == 0) ? flashData.liquidEos : flashData.vapourEos; - EquationOfStateType const incipientEos = sampleEos; + EquationOfStateType const incipientEos = (configStep == 0) ? flashData.vapourEos : flashData.liquidEos; real64 tpd = 0.0; @@ -110,13 +119,14 @@ bool StabilityTest::compute( integer const numComps, logFugacity, hyperplane ); - for( real64 const alpha : { 1.0, -1.0, 0.0 } ) + for( int const alpha : { 1, -1, 0 } ) { - if( LvArray::math::abs( alpha ) < MultiFluidConstants::epsilon ) + // If alpha is zero then it means we want to test a constant composition + if( alpha == 0 ) { for( integer const ic : presentComponents ) { - logTestComposition[ic] = 1.0; + logTestComposition[ic] = 0.0; } } else @@ -124,7 +134,7 @@ bool StabilityTest::compute( integer const numComps, for( integer const ic : presentComponents ) { real64 const logK = LvArray::math::log( kValues[ic] ); - logTestComposition[ic] = LvArray::math::log( composition[ic] ) + alpha * logK; + logTestComposition[ic] = LvArray::math::log( composition[ic] ) + (1.0/alpha) * logK; } } @@ -167,7 +177,7 @@ bool StabilityTest::compute( integer const numComps, } // Start with Newton iterations - for(iterationCount++; (!converged) && (iterationCount < maxIterations); ++iterationCount ) + for( iterationCount++; (!converged) && (iterationCount < maxIterations); ++iterationCount ) { for( integer const ic : presentComponents ) { @@ -187,6 +197,8 @@ bool StabilityTest::compute( integer const numComps, derivatives.toSlice(), residual, jacobian.toSlice() ); + + // Ensure that the Jacobian is well formed for the absent components for( integer const ic : absentComponents ) { jacobian( ic, ic ) = 1.0; @@ -203,7 +215,6 @@ bool StabilityTest::compute( integer const numComps, } allConverged = allConverged && converged; - // Calculate the tangent-plane-distance (TPD) and distance to the trivial solution real64 distance = 0.0; for( integer const ic : presentComponents ) @@ -212,18 +223,6 @@ bool StabilityTest::compute( integer const numComps, distance += (dZ*dZ); } - // The incipient phase composition is the converged test composition that is furthest away from the - // given sample composition - if( maxDistanceToTrivialSolution < distance ) - { - maxDistanceToTrivialSolution = distance; - incipientEquationOfState = incipientEos; - for( integer ic = 0; ic < numComps; ++ic ) - { - incipientComposition[ic] = testComposition[ic]; - } - } - // The mixture is unstable if either the TPD is negative or if the TPD is zero but the incipient composition // is different from the sample composition // stabilityThreshold is negative (default -1e-8) @@ -235,10 +234,17 @@ bool StabilityTest::compute( integer const numComps, { unstableMixture = true; } + if( unstableMixture ) { + storeIncipientComposition( incipientEos ); return true; } + else if( maxDistanceToTrivialSolution < distance ) + { + maxDistanceToTrivialSolution = distance; + storeIncipientComposition( incipientEos ); + } } } @@ -264,19 +270,46 @@ void StabilityTest::computeDerivatives( integer const numComps, integer const numDofs = 2 + numComps; - StackArray< real64, 1, maxNumComps > logFugacity( numComps ); + StackArray< real64, 2, 3*maxNumComps > workSpace( 3, numComps ); + arraySlice1d< real64 > logFugacitySample = workSpace[0]; + arraySlice1d< real64 > logFugacityIncipient = workSpace[1]; + arraySlice1d< real64 > normalisedComposition = workSpace[2]; + StackArray< real64, 2, maxNumRows * maxNumRows, MatrixLayout::COL_MAJOR_PERM > A( numComps + 1, numComps + 1 ); + StackArray< real64, 2, maxNumRows * maxNumDofs, MatrixLayout::COL_MAJOR_PERM > X( numComps + 1, numDofs ); + auto const & logFugacityIncipientDerivs = incipientCompositionDerivs; auto const & logFugacitySampleDerivs = compositionDerivs; + // Normalise the composition vector + copyComposition( numComps, composition, normalisedComposition ); + real64 const totalAmount = normalizeComposition( numComps, normalisedComposition ); + real64 const invTotalAmount = totalAmount < MultiFluidConstants::epsilon ? 0.0 : 1.0 / totalAmount; FugacityCalculator::computeLogFugacityDerivatives( numComps, pressure, temperature, - composition, + normalisedComposition.toSliceConst(), componentProperties, sampleEquationOfState, flashData, - logFugacity.toSlice(), + logFugacitySample, logFugacitySampleDerivs ); + + // Include the normalisation in the composition derivatives (chain rule): + // dx_j/dz_k = (delta_jk - x_j) / sum(z) + // dlnphi_i/dz_k = ( dlnphi_i/dx_k - sum_j( dlnphi_i/dx_j x_j ) ) / sum(z) + for( integer ic = 0; ic < numComps; ++ic ) + { + real64 weightedSum = 0.0; + for( integer jc = 0; jc < numComps; ++jc ) + { + weightedSum += logFugacitySampleDerivs( ic, Deriv::dC+jc ) * normalisedComposition[jc]; + } + for( integer kc = 0; kc < numComps; ++kc ) + { + logFugacitySampleDerivs( ic, Deriv::dC+kc ) = (logFugacitySampleDerivs( ic, Deriv::dC+kc ) - weightedSum) * invTotalAmount; + } + } + FugacityCalculator::computeLogFugacityDerivatives( numComps, pressure, temperature, @@ -284,11 +317,12 @@ void StabilityTest::computeDerivatives( integer const numComps, componentProperties, incipientEquationOfState, flashData, - logFugacity.toSlice(), + logFugacityIncipient, logFugacityIncipientDerivs ); - StackArray< real64, 2, maxNumRows * maxNumRows, MatrixLayout::COL_MAJOR_PERM > A( numComps + 1, numComps + 1 ); - StackArray< real64, 2, maxNumRows * maxNumDofs, MatrixLayout::COL_MAJOR_PERM > X( numComps + 1, numDofs ); + integer const refComp = getReferenceComponent( numComps, incipientComposition ); + real64 const logRatioRef = refComp < 0 ? 0.0 : logFugacitySample[refComp] - logFugacityIncipient[refComp]; + real64 const yOverZRef = refComp < 0 ? 0.0 : incipientComposition[refComp] / composition[refComp]; for( integer ic = 0; ic < numComps; ++ic ) { @@ -316,10 +350,16 @@ void StabilityTest::computeDerivatives( integer const numComps, integer const idof = Deriv::dC + jc; X( ic, idof ) = yi*logFugacitySampleDerivs( ic, idof ); } - if( MultiFluidConstants::epsilon < composition[ic] ) + if( MultiFluidConstants::minForSpeciesPresence < composition[ic] ) { X( ic, Deriv::dC+ic ) += yi/composition[ic]; } + else + { + // Absent component: y_k = r_k z_k => dy_k/dz_k = r_k (one-sided derivative at z_k = 0) + real64 const logRatio = logFugacitySample[ic] - logFugacityIncipient[ic]; + X( ic, Deriv::dC+ic ) = yOverZRef * LvArray::math::exp( logRatio - logRatioRef ); + } } for( integer idof = 0; idof < numDofs; ++idof ) { diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp index 9395cf5a8c8..89e483b4730 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/functions/Utilities.hpp @@ -38,6 +38,25 @@ GEOS_HOST_DEVICE GEOS_FORCE_INLINE static void setZero( real64 & value ){ value = 0.0; } +/** + * @brief Compies a composition from one array to another + * @param[in] numComps number of components + * @param[in] inputComposition input composition to be copied + * @param[out] outputComposition output composition to be copied into + */ +template< integer USD1, integer USD2 > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +static void copyComposition( integer const numComps, + arraySlice1d< real64 const, USD1 > const & inputComposition, + arraySlice1d< real64, USD2 > const & outputComposition ) +{ + for( integer ic = 0; ic < numComps; ++ic ) + { + outputComposition[ic] = inputComposition[ic]; + } +} + /** * @brief Normalise a composition in place to ensure that the components add up to unity * @param[in] numComps number of components @@ -63,6 +82,31 @@ static real64 normalizeComposition( integer const numComps, return totalMoles; } +/** + * @brief Find the reference component - the index of the component with the largest composition + * @param[in] numComps number of components + * @param[in] composition composition to be assessed + * @return the index of the component with the largest composition + */ +template< integer USD > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +static integer getReferenceComponent( integer const numComps, + arraySlice1d< real64 const, USD > const & composition ) +{ + real64 maxComposition = -LvArray::NumericLimits< real64 >::max; + integer refComponent = -1; + for( integer ic = 0; ic < numComps; ++ic ) + { + if( maxComposition < composition[ic] ) + { + refComponent = ic; + maxComposition = composition[ic]; + } + } + return refComponent; +} + /** * @brief Checks if a composition array has numerically small values * @param[in] numComps number of values in the composition array @@ -185,15 +229,15 @@ static bool checkPureMixture( integer const numComps, } /** - * @brief Solve the lineat system for the derivatives of the flash + * @brief Solve the linear system for the derivatives of the flash * @param[in/out] A the coefficient matrix. Destroyed after call * @param[in/out] X the rhs and solution * @return @c true if the problem is well solved @c false otherwise */ -template< int USD > +template< int USD, typename RHS_TYPE > GEOS_HOST_DEVICE static bool solveLinearSystem( arraySlice2d< real64, USD > const & A, - arraySlice2d< real64, USD > const & X ) + RHS_TYPE const & X ) { #if defined(GEOS_DEVICE_COMPILE) return denseLinearAlgebra::solveGaussianElimination( A, X ); @@ -203,27 +247,6 @@ static bool solveLinearSystem( arraySlice2d< real64, USD > const & A, #endif } -/** - * @brief Solve the lineat system for the derivatives of the flash - * @param[in/out] A the coefficient matrix. Destroyed after call - * @param[in/out] X the rhs and solution - * @return @c true if the problem is well solved @c false otherwise - */ -template< int USD1, int USD2 > -GEOS_HOST_DEVICE -static bool solveLinearSystem( arraySlice2d< real64, USD1 > const & A, - arraySlice1d< real64, USD2 > const & x ) -{ -#if defined(GEOS_DEVICE_COMPILE) - GEOS_UNUSED_VAR( A ); - GEOS_UNUSED_VAR( x ); - return false; -#else - BlasLapackLA::solveLinearSystem( A, x ); - return true; -#endif -} - } // namespace compositional } // namespace constitutive } // namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp index fc87de3267c..ab40bbbd80a 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/parameters/FlashParameters.cpp @@ -21,6 +21,7 @@ #include "ComponentProperties.hpp" #include "constitutive/fluid/multifluid/MultiFluidBase.hpp" +#include "common/MpiWrapper.hpp" namespace geos { @@ -70,7 +71,7 @@ void FlashParameters::registerParametersImpl( MultiFluidBase * fluid ) fluid->registerWrapper( viewKeyStruct::stabilityMaxIterationsString(), &m_discreteParameters[STABILITY_MAX_ITERATIONS] ). setInputFlag( dataRepository::InputFlags::OPTIONAL ). setDefaultValue( m_discreteParameters[STABILITY_MAX_ITERATIONS] ). - setDescription( "The maximum number of successive substitution iterations used during the stability test. " + setDescription( "The maximum number of iterations used during the stability test. " "A zero or negative value skips the stability test" ); fluid->registerWrapper( viewKeyStruct::flashMaxIterationsString(), &m_discreteParameters[FLASH_MAX_ITERATIONS] ). @@ -136,6 +137,24 @@ void FlashParameters::postInputInitializationImpl( MultiFluidBase const * fluid, real64 const ssiTolerance = m_continuousParameters[SSI_TOLERANCE]; checkLowerBound( ssiTolerance, epsilon, viewKeyStruct::ssiToleranceString() ); + // If the SSI tolerance is lower than the stability tolerance then it will be ignored for stability + if( ssiTolerance < stabilityTolerance ) + { + GEOS_WARNING_IF( MpiWrapper::commRank() == 0, + GEOS_FMT( "The SSI tolerance {} is less than the stability tolerance {}. " + "The SSI tolerance will be ignored for stability calculations.", + ssiTolerance, stabilityTolerance )); + } + + // If the SSI tolerance is lower than the flash tolerance then it will be ignored for flash + if( ssiTolerance < flashTolerance ) + { + GEOS_WARNING_IF( MpiWrapper::commRank() == 0, + GEOS_FMT( "The SSI tolerance {} is less than the flash tolerance {}. " + "The SSI tolerance will be ignored for flash calculations.", + ssiTolerance, flashTolerance )); + } + // Max number of flash iterations should be at least 1 integer const flashMaxIterations = m_discreteParameters[FLASH_MAX_ITERATIONS]; checkLowerBound( flashMaxIterations, 1, viewKeyStruct::flashMaxIterationsString() ); diff --git a/src/coreComponents/constitutive/unitTests/CMakeLists.txt b/src/coreComponents/constitutive/unitTests/CMakeLists.txt index b5381770f19..916034e85a9 100644 --- a/src/coreComponents/constitutive/unitTests/CMakeLists.txt +++ b/src/coreComponents/constitutive/unitTests/CMakeLists.txt @@ -40,6 +40,7 @@ set( gtest_geosx_tests testSoreideWhitsonFlash.cpp testStabilityTest2Comp.cpp testStabilityTest9Comp.cpp + testStabilityTestDerivatives.cpp testStabilityTestJacobian.cpp testRachfordRice.cpp testTwoPhaseImmiscibleFluid.cpp ) diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp index 9ac72d272de..d25f59f4653 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest2Comp.cpp @@ -81,6 +81,7 @@ class StabilityTestTest2CompFixture : public ::testing::TestWithParam< Stabilit auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); auto const * flashParameters = parameters->get< FlashParameters >(); + flashParameters->m_discreteParameters[FlashParameters::STABILITY_MAX_ITERATIONS] = 20; bool const stabilityStatus = StabilityTest::compute( numComps, pressure, diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp index 07e3ee5bf41..33194bb05f9 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTest9Comp.cpp @@ -82,6 +82,7 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< Stabilit auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); auto const * flashParameters = parameters->get< FlashParameters >(); + setMaximumNumberOfIterations( flashParameters, 20 ); bool const stabilityStatus = StabilityTest::compute( numComps, pressure, @@ -99,7 +100,7 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< Stabilit // Expect this to succeed ASSERT_EQ( stabilityStatus, true ); - // Check the stability labe; + // Check the stability label ASSERT_EQ( unstableMixture, expectedUnstableMixture ); // Check the incipient methane fraction @@ -138,6 +139,7 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< Stabilit auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); auto const * flashParameters = parameters->get< FlashParameters >(); + setMaximumNumberOfIterations( flashParameters, 20 ); StabilityTest::compute( numComps, pressure, @@ -167,33 +169,45 @@ class StabilityTestTest9CompFixture : public ::testing::TestWithParam< Stabilit liquidComposition, vapourComposition ); - // Expect this to succeed - ASSERT_EQ( status, true ); - - constexpr real64 epsilon = MultiFluidConstants::epsilon; - real64 const V = vapourFraction; - real64 const L = 1.0 - V; + // Expect the flash to succeed for an unstable mixture + ASSERT_EQ( status || !unstableMixture, true ); - // Check stability vs flash - if( unstableMixture ) + if( status ) { - // Unstable mixture: both L and V should be positive - ASSERT_GT( V, epsilon ); - ASSERT_GT( L, epsilon ); - } - else - { - // Stable mixture: one of L or V should be zero - ASSERT_TRUE( V < epsilon || L < epsilon ); + constexpr real64 epsilon = MultiFluidConstants::epsilon; + real64 const V = vapourFraction; + real64 const L = 1.0 - V; + + // Check stability vs flash + if( unstableMixture ) + { + // Unstable mixture: both L and V should be positive + ASSERT_GT( V, epsilon ); + ASSERT_GT( L, epsilon ); + } + else + { + // Stable mixture: one of L or V should be zero + ASSERT_TRUE( V < epsilon || L < epsilon ); + } } } protected: std::unique_ptr< TestFluid< numComps > > m_fluid{}; private: + static void setMaximumNumberOfIterations( FlashParameters const * parameters, integer const maxIterations ); static std::unique_ptr< TestFluid< numComps > > createFluid(); }; +template< EquationOfStateType EOS_TYPE > +void StabilityTestTest9CompFixture< EOS_TYPE >::setMaximumNumberOfIterations( FlashParameters const * parameters, + integer const maxIterations ) +{ + auto * flashParameters = const_cast< FlashParameters * >(parameters); + flashParameters->m_discreteParameters[FlashParameters::STABILITY_MAX_ITERATIONS] = maxIterations; +} + template< EquationOfStateType EOS_TYPE > std::unique_ptr< TestFluid< numComps > > StabilityTestTest9CompFixture< EOS_TYPE >::createFluid() { @@ -220,6 +234,7 @@ std::unique_ptr< TestFluid< numComps > > StabilityTestTest9CompFixture< EOS_TYPE using PengRobinson = StabilityTestTest9CompFixture< EquationOfStateType::PengRobinson >; using SoaveRedlichKwong = StabilityTestTest9CompFixture< EquationOfStateType::SoaveRedlichKwong >; + TEST_P( PengRobinson, testStabilityTest ) { testStability( GetParam() ); @@ -246,22 +261,118 @@ TEST_P( SoaveRedlichKwong, testStabilityWithFlash ) INSTANTIATE_TEST_SUITE_P( StabilityTest, PengRobinson, ::testing::ValuesIn({ - {1.0e+05, 288.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99992981}, - {1.0e+05, 297.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99989343}, - {1.0e+05, 353.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99906841}, - {1.0e+05, 393.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99685491}, - {1.0e+05, 573.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, false, 0.16920000} + {1.0e+05, 288.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 9.99930e-01}, + {1.0e+05, 298.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 9.99889e-01}, + {1.0e+05, 353.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 9.99068e-01}, + {1.0e+05, 573.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, false, 1.69200e-01}, + {5.0e+06, 288.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 3.31496e-06}, + {5.0e+06, 298.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 6.19514e-06}, + {5.0e+06, 353.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 1.68840e-04}, + {5.0e+06, 573.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 7.60017e-01}, + {1.0e+07, 288.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 4.69115e-05}, + {1.0e+07, 298.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 6.37278e-05}, + {1.0e+07, 353.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 4.72565e-04}, + {1.0e+07, 573.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 5.69337e-01}, + {1.0e+08, 288.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, false, 1.69200e-01}, + {1.0e+08, 298.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, false, 1.69200e-01}, + {1.0e+08, 353.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, false, 1.69200e-01}, + {1.0e+08, 573.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, false, 1.69200e-01}, + {1.0e+05, 288.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 9.99931e-01}, + {1.0e+05, 298.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 9.99891e-01}, + {1.0e+05, 353.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 9.99113e-01}, + {1.0e+05, 573.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, false, 1.69187e-01}, + {5.0e+06, 288.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 3.10425e-06}, + {5.0e+06, 298.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 5.93265e-06}, + {5.0e+06, 353.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 2.11049e-04}, + {5.0e+06, 573.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 7.78486e-01}, + {1.0e+07, 288.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 3.30848e-05}, + {1.0e+07, 298.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 4.73576e-05}, + {1.0e+07, 353.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 4.31414e-04}, + {1.0e+07, 573.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 6.09508e-01}, + {1.0e+08, 288.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, false, 1.69187e-01}, + {1.0e+08, 298.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, false, 1.69187e-01}, + {1.0e+08, 353.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, false, 1.69187e-01}, + {1.0e+08, 573.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, false, 1.69187e-01}, + {1.0e+05, 288.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 9.99380e-01}, + {1.0e+05, 298.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 9.99048e-01}, + {1.0e+05, 353.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 9.93558e-01}, + {1.0e+05, 573.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.11112e-01}, + {5.0e+06, 288.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 1.20037e-06}, + {5.0e+06, 298.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 2.41217e-06}, + {5.0e+06, 353.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 6.49045e-05}, + {5.0e+06, 573.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.11112e-01}, + {1.0e+07, 288.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.43584e-05}, + {1.0e+07, 298.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 2.41543e-05}, + {1.0e+07, 353.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 3.04002e-04}, + {1.0e+08, 288.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.11112e-01}, + {1.0e+08, 298.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.11112e-01}, + {1.0e+08, 353.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.11112e-01}, + {1.0e+08, 573.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.11112e-01}, + {1.0e+05, 573.15, {0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.0000000e+00}, false, 1.00000e+00}, + {1.0e+08, 288.15, {0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.0000000e+00}, false, 1.00000e+00}, + {1.0e+05, 573.15, {0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.3300000e-05, 1.3300000e-05, 9.9997340e-01}, false, 9.99973e-01}, + {1.0e+08, 288.15, {0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.3300000e-05, 1.3300000e-05, 9.9997340e-01}, false, 9.99973e-01}, + {1.0e+05, 573.15, {0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.3300000e-05, 9.9997340e-01, 1.3300000e-05}, false, 1.33000e-05}, + {1.0e+08, 288.15, {0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.3300000e-05, 9.9997340e-01, 1.3300000e-05}, false, 1.33000e-05} }) ); INSTANTIATE_TEST_SUITE_P( StabilityTest, SoaveRedlichKwong, ::testing::ValuesIn({ - {1.0e+05, 288.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99994255}, - {1.0e+05, 297.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99991141}, - {1.0e+05, 353.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99916193}, - {1.0e+05, 393.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, true, 0.99704625}, - {1.0e+05, 573.15, { 0.0090, 0.0030, 0.5347, 0.1146, 0.0879, 0.0456, 0.0209, 0.0151, 0.1692 }, false, 0.16920000} + {1.0e+05, 288.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 9.99943e-01}, + {1.0e+05, 298.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 9.99907e-01}, + {1.0e+05, 353.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 9.99162e-01}, + {1.0e+05, 573.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, false, 1.69200e-01}, + {5.0e+06, 288.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 2.35604e-06}, + {5.0e+06, 298.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 4.52623e-06}, + {5.0e+06, 353.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 1.34208e-04}, + {5.0e+06, 573.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 7.61380e-01}, + {1.0e+07, 288.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 3.24422e-05}, + {1.0e+07, 298.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 4.49843e-05}, + {1.0e+07, 353.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 3.62686e-04}, + {1.0e+07, 573.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, true, 5.80899e-01}, + {1.0e+08, 288.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, false, 1.69200e-01}, + {1.0e+08, 298.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, false, 1.69200e-01}, + {1.0e+08, 353.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, false, 1.69200e-01}, + {1.0e+08, 573.15, {9.0000000e-03, 3.0000000e-03, 5.3470000e-01, 1.1460000e-01, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6920000e-01}, false, 1.69200e-01}, + {1.0e+05, 288.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 9.99944e-01}, + {1.0e+05, 298.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 9.99909e-01}, + {1.0e+05, 353.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 9.99202e-01}, + {1.0e+05, 573.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, false, 1.69187e-01}, + {5.0e+06, 288.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 2.21223e-06}, + {5.0e+06, 298.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 4.33855e-06}, + {5.0e+06, 353.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 1.63405e-04}, + {5.0e+06, 573.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 7.79335e-01}, + {1.0e+07, 288.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 2.28707e-05}, + {1.0e+07, 298.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 3.33621e-05}, + {1.0e+07, 353.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 3.27432e-04}, + {1.0e+07, 573.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, true, 6.18577e-01}, + {1.0e+08, 288.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, false, 1.69187e-01}, + {1.0e+08, 298.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, false, 1.69187e-01}, + {1.0e+08, 353.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, false, 1.69187e-01}, + {1.0e+08, 573.15, {9.0000000e-03, 0.0000000e+00, 6.5230000e-01, 1.3300000e-05, 8.7900000e-02, 4.5600000e-02, 2.0900000e-02, 1.5100000e-02, 1.6918670e-01}, false, 1.69187e-01}, + {1.0e+05, 288.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 9.99489e-01}, + {1.0e+05, 298.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 9.99201e-01}, + {1.0e+05, 353.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 9.94186e-01}, + {1.0e+05, 573.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.11112e-01}, + {5.0e+06, 288.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 8.06893e-07}, + {5.0e+06, 298.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 1.68319e-06}, + {5.0e+06, 353.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 5.24670e-05}, + {5.0e+06, 573.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.11112e-01}, + {1.0e+07, 288.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 8.46960e-06}, + {1.0e+07, 298.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 1.49116e-05}, + {1.0e+07, 353.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, true, 2.25256e-04}, + {1.0e+08, 288.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.11112e-01}, + {1.0e+08, 298.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.11112e-01}, + {1.0e+08, 353.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.11112e-01}, + {1.0e+08, 573.15, {1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111100e-01, 1.1111200e-01}, false, 1.11112e-01}, + {1.0e+05, 573.15, {0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.0000000e+00}, false, 1.00000e+00}, + {1.0e+08, 288.15, {0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.0000000e+00}, false, 1.00000e+00}, + {1.0e+05, 573.15, {0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.3300000e-05, 1.3300000e-05, 9.9997340e-01}, false, 9.99973e-01}, + {1.0e+08, 288.15, {0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.3300000e-05, 1.3300000e-05, 9.9997340e-01}, false, 9.99973e-01}, + {1.0e+05, 573.15, {0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.3300000e-05, 9.9997340e-01, 1.3300000e-05}, false, 1.33000e-05}, + {1.0e+08, 288.15, {0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 1.3300000e-05, 9.9997340e-01, 1.3300000e-05}, false, 1.33000e-05} }) ); diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTestDerivatives.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTestDerivatives.cpp new file mode 100644 index 00000000000..cc53cb3e004 --- /dev/null +++ b/src/coreComponents/constitutive/unitTests/testStabilityTestDerivatives.cpp @@ -0,0 +1,372 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +// Source includes +#include "codingUtilities/UnitTestUtilities.hpp" +#include "constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp" +#include "constitutive/fluid/multifluid/MultiFluidConstants.hpp" +#include "TestFluid.hpp" +#include "TestFluidUtilities.hpp" + +using namespace geos::constitutive; +using namespace geos::constitutive::compositional; + +namespace geos +{ +namespace testing +{ + +static constexpr std::array< real64, 4 > testPressures{1.0, 50.0, 100.0, 500.0}; // Pressure in bars +static constexpr std::array< real64, 4 > testTemperature{10.0, 25.0, 80.0, 150.0}; // Temperature in C + +template< integer NC > +struct FluidData +{}; + +template<> +struct FluidData< 2 > +{ + static constexpr real64 e = 1.0e-6; + + static constexpr std::array< real64, 8 > testCompositions = { + 0.5, 0.5, + 0.0, 1.0, + e, 1.0-e, + 1.0-e, e + }; + + static std::unique_ptr< TestFluid< 2 > > createFluid() + { + auto fluid = TestFluid< 2 >::create( {Fluid::CO2, Fluid::H2O} ); + fluid->setBinaryCoefficients( Feed< 1 >{0.1896} ); + return fluid; + } +}; + +template<> +struct FluidData< 4 > +{ + static constexpr real64 e = 1.0e-6; + + static constexpr std::array< real64, 16 > testCompositions = { + 0.3, 0.2, 0.2, 0.3, + 0.0, 0.0, 0.0, 1.0, + 0.0, 0.5, 0.0, 0.5, + e, e, e, 1.0-3*e + }; + + static std::unique_ptr< TestFluid< 4 > > createFluid() + { + auto fluid = TestFluid< 4 >::create( {Fluid::CH4, Fluid::CO2, Fluid::H2S, Fluid::H2O} ); + const std::array< real64 const, 6 > bics = { 0.0, 0.0, 0.0, 0.4850, 0.1896, 0.1353 }; + fluid->setBinaryCoefficients( bics ); + return fluid; + } +}; + +template<> +struct FluidData< 6 > +{ + static constexpr real64 e = 1.0e-7; + static constexpr real64 f = 0.16666; + + static constexpr std::array< real64, 30 > testCompositions = { + f, f, f, f, f, 1.0-5*f, + e, e, e, e, e, 1.0-5*e, + e, 1.0-5*e, e, e, e, e, + 0.260871, 0.0663935, 0.0906286, 0.0524321, 0.52755293, 0.00212187, + 6.233e-08, 2.99791e-09, 8.00657e-06, 8.187700789e-05, 5.10942e-08, 0.99991 + }; + + static std::unique_ptr< TestFluid< 6 > > createFluid() + { + auto fluid = TestFluid< 6 >::create( {Fluid::CH4, Fluid::C2H6, Fluid::CO2, Fluid::H2S, Fluid::N2, Fluid::H2O} ); + const std::array< real64 const, 15 > bics = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4850, 0.4920, 0.1896, 0.1353, 0.4778 }; + fluid->setBinaryCoefficients( bics ); + return fluid; + } +}; + +template< integer NC > +using FlashData = std::tuple< + real64 const, // pressure + real64 const, // temperature + Feed< NC > const // total composition + >; + +template< integer NC, EquationOfStateType EOS_TYPE > +class StabilityTestDerivativesTestFixture : public ::testing::TestWithParam< FlashData< NC > > +{ + static constexpr real64 relTol = 1.0e-5; + static constexpr real64 absTol = 1.0e-7; + static constexpr integer numComps = NC; + static constexpr integer numDofs = NC + 2; + + using Deriv = geos::constitutive::multifluid::DerivativeOffset; + +public: + StabilityTestDerivativesTestFixture() + : m_fluid( FluidData< NC >::createFluid() ) + {} + + ~StabilityTestDerivativesTestFixture() = default; + + void testStabilityTestDerivatives( FlashData< NC > const & data ) + { + auto componentProperties = this->m_fluid->createKernelWrapper(); + + // Extract test point + real64 const pressure = std::get< 0 >( data ); + real64 const temperature = std::get< 1 >( data ); + stackArray1d< real64, numComps > composition; + TestFluid< NC >::createArray( composition, std::get< 2 >( data )); + + StackArray< real64, 2, 4*numComps > workSpace( 4, numComps ); + StackArray< real64, 3, 2*numComps *numDofs > derivativeWorkSpace( 2, numComps, numDofs ); + arraySlice1d< real64 > incipientComposition = workSpace[0]; + arraySlice1d< real64 > kValues = workSpace[1]; + arraySlice1d< real64 > derivatives = workSpace[2]; + arraySlice1d< real64 > displacedIncipientComposition = workSpace[3]; + arraySlice2d< real64 > sampleDerivatives = derivativeWorkSpace[0]; + arraySlice2d< real64 > incipientDerivatives = derivativeWorkSpace[1]; + + auto const setZero = []( real64 & value ){ value = 0.0; }; + + LvArray::forValuesInSlice( workSpace.toSlice(), setZero ); + + EquationOfStateType constexpr equationOfState = EOS_TYPE; + + constitutive::compositional::FlashData flashData; + flashData.liquidEos = equationOfState; + if constexpr (equationOfState == EquationOfStateType::SoreideWhitson) + { + flashData.vapourEos = EquationOfStateType::PengRobinson; + } + else + { + flashData.vapourEos = equationOfState; + } + + // Extract column + auto const extractColumn = [&]( integer const idof, real64 const scale = 1.0 ) + { + for( integer ic = 0; ic < numComps; ++ic ) + { + derivatives[ic] = scale * incipientDerivatives( ic, idof ); + } + }; + + if constexpr (equationOfState == EquationOfStateType::SoreideWhitson) + { + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + pressure, + temperature, + componentProperties, + kValues ); + } + else + { + KValueInitialization::computeSoreideWhitsonKvalue( numComps, + pressure, + temperature, + componentProperties, + composition.toSliceConst(), + kValues ); + } + + auto const parameters = FlashParameters::create( std::make_unique< ModelParameters >() ); + auto const * flashParameters = parameters->get< FlashParameters >(); + flashParameters->m_discreteParameters[FlashParameters::STABILITY_MAX_ITERATIONS] = 20; + + bool unstableMixture = false; + EquationOfStateType outputEos = EOS_TYPE; + bool const stabilityStatus = StabilityTest::compute( numComps, + pressure, + temperature, + composition.toSliceConst(), + componentProperties, + flashData, + kValues.toSliceConst(), + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, + unstableMixture, + outputEos, + incipientComposition ); + EXPECT_EQ( stabilityStatus, true ); + + EquationOfStateType const sampleEos = (outputEos == flashData.vapourEos) ? flashData.liquidEos : flashData.vapourEos; + StabilityTest::computeDerivatives( numComps, + pressure, + temperature, + composition.toSliceConst(), + componentProperties, + sampleEos, + outputEos, + flashData, + incipientComposition.toSliceConst(), + incipientDerivatives, + sampleDerivatives ); + + // -- Pressure derivative + extractColumn( Deriv::dP ); + real64 const dp = 1.0e-4 * pressure; + geos::testing::internal::testNumericalDerivative< numComps >( + pressure, dp, derivatives, + [&]( real64 const p, auto & values ){ + bool displacedUnstableMixture = false; + EquationOfStateType displacedOutputEos = EOS_TYPE; + StabilityTest::compute( numComps, + p, + temperature, + composition.toSliceConst(), + componentProperties, + flashData, + kValues.toSliceConst(), + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, + displacedUnstableMixture, + displacedOutputEos, + displacedIncipientComposition ); + for( integer ic = 0; ic < numComps; ++ic ) + { + values[ic] = displacedIncipientComposition[ic]; + } + } ); + + // -- Temperature derivative + extractColumn( Deriv::dT ); + real64 const dT = 1.0e-5 * temperature; + geos::testing::internal::testNumericalDerivative< numComps >( + temperature, dT, derivatives, + [&]( real64 const t, auto & values ){ + bool displacedUnstableMixture = false; + EquationOfStateType displacedOutputEos = EOS_TYPE; + StabilityTest::compute( numComps, + pressure, + t, + composition.toSliceConst(), + componentProperties, + flashData, + kValues.toSliceConst(), + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, + displacedUnstableMixture, + displacedOutputEos, + displacedIncipientComposition ); + for( integer ic = 0; ic < numComps; ++ic ) + { + values[ic] = displacedIncipientComposition[ic]; + } + } ); + + // -- Composition derivatives + real64 constexpr dz = 1.0e-9; + for( integer kc = 0; kc < numComps; ++kc ) + { + // If the mixture is stable and the component doesn't exist then checking the derivative here will + // not work because the incipient phase composition is not continuous in the component dimension. + if( composition[kc] < MultiFluidConstants::minForSpeciesPresence && !unstableMixture ) + { + continue; + } + extractColumn( Deriv::dC + kc ); + geos::testing::internal::testNumericalDerivative< numComps >( + 0.0, dz, derivatives, + [&]( real64 const z, auto & values ){ + real64 const zOld = composition[kc]; + composition[kc] += z; + bool displacedUnstableMixture = false; + EquationOfStateType displacedOutputEos = EOS_TYPE; + StabilityTest::compute( numComps, + pressure, + temperature, + composition.toSliceConst(), + componentProperties, + flashData, + kValues.toSliceConst(), + flashParameters->m_continuousParameters, + flashParameters->m_discreteParameters, + displacedUnstableMixture, + displacedOutputEos, + displacedIncipientComposition ); + + for( integer ic = 0; ic < numComps; ++ic ) + { + values[ic] = displacedIncipientComposition[ic]; + } + composition[kc] = zOld; + } ); + } + } + +protected: + std::unique_ptr< TestFluid< NC > > m_fluid{}; +}; + +using SoaveRedlichKwong2 = StabilityTestDerivativesTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; +using PengRobinson4 = StabilityTestDerivativesTestFixture< 4, EquationOfStateType::PengRobinson >; +using SoreideWhitson6 = StabilityTestDerivativesTestFixture< 6, EquationOfStateType::SoreideWhitson >; + +TEST_P( SoaveRedlichKwong2, testDerivatives ) +{ + testStabilityTestDerivatives( GetParam() ); +} + +TEST_P( PengRobinson4, testDerivatives ) +{ + testStabilityTestDerivatives( GetParam() ); +} + +TEST_P( SoreideWhitson6, testDerivatives ) +{ + testStabilityTestDerivatives( GetParam() ); +} + +//------------------------------------------------------------------------------- +// Data +//------------------------------------------------------------------------------- + +template< integer NC > +stdVector< FlashData< NC > > generateData() +{ + constexpr integer dataSize = static_cast< integer >(FluidData< NC >::testCompositions.size()); + integer constexpr numSamples = dataSize / NC; + static_assert( numSamples * NC == dataSize ); + + stdVector< FlashData< NC > > data; + for( integer sampleIndex = 0; sampleIndex < numSamples; sampleIndex++ ) + { + Feed< NC > sample; + for( integer ic = 0; ic < NC; ic++ ) + { + sample[ic] = FluidData< NC >::testCompositions[sampleIndex*NC + ic]; + } + for( real64 const p : testPressures ) // Pressure in bars + { + for( real64 const t : testTemperature ) // Temperature in C + { + data.emplace_back( 1.0e5*p, t + 273.15, sample ); + } + } + } + return data; +} + +INSTANTIATE_TEST_SUITE_P( StabilityTestDerivatives, SoaveRedlichKwong2, ::testing::ValuesIn( generateData< 2 >()) ); +INSTANTIATE_TEST_SUITE_P( StabilityTestDerivatives, PengRobinson4, ::testing::ValuesIn( generateData< 4 >()) ); +INSTANTIATE_TEST_SUITE_P( StabilityTestDerivatives, SoreideWhitson6, ::testing::ValuesIn( generateData< 6 >()) ); + +} // testing +} // geos diff --git a/src/coreComponents/constitutive/unitTests/testStabilityTestJacobian.cpp b/src/coreComponents/constitutive/unitTests/testStabilityTestJacobian.cpp index 61118275054..fa86274cc94 100644 --- a/src/coreComponents/constitutive/unitTests/testStabilityTestJacobian.cpp +++ b/src/coreComponents/constitutive/unitTests/testStabilityTestJacobian.cpp @@ -18,9 +18,11 @@ #include "constitutive/fluid/multifluid/compositional/functions/StabilityTest.hpp" #include "constitutive/fluid/multifluid/compositional/functions/KValueInitialization.hpp" #include "constitutive/fluid/multifluid/compositional/functions/Utilities.hpp" +#include "constitutive/fluid/multifluid/MultiFluidConstants.hpp" #include "TestFluid.hpp" #include "TestFluidUtilities.hpp" +using namespace geos::constitutive; using namespace geos::constitutive::compositional; namespace geos @@ -28,16 +30,26 @@ namespace geos namespace testing { -template< int NC > +template< integer NC > struct FluidData {}; template<> struct FluidData< 2 > { + static constexpr real64 e = 1.0e-8; + + static constexpr std::array< real64, 8 > testCompositions = { + 0.5, 0.5, + 0.0, 1.0, + e, 1.0-e, + 1.0-e, e + }; + static std::unique_ptr< TestFluid< 2 > > createFluid() { auto fluid = TestFluid< 2 >::create( {Fluid::CO2, Fluid::C5H12} ); + fluid->setBinaryCoefficients( Feed< 1 >{0.025} ); return fluid; } }; @@ -45,13 +57,25 @@ struct FluidData< 2 > template<> struct FluidData< 4 > { + static constexpr real64 e = 1.0e-7; + + static constexpr std::array< real64, 16 > testCompositions = { + 0.3, 0.2, 0.2, 0.3, + 0.0, 0.0, 0.0, 1.0, + 0.0, 0.5, 0.0, 0.5, + e, e, 0.0, 1.0-2*e + }; + static std::unique_ptr< TestFluid< 4 > > createFluid() { - return TestFluid< 4 >::create( {Fluid::N2, Fluid::CH4, Fluid::CO2, Fluid::H2O} ); + auto fluid = TestFluid< 4 >::create( {Fluid::CH4, Fluid::CO2, Fluid::H2S, Fluid::H2O} ); + const std::array< real64 const, 6 > bics = { 0.0, 0.0, 0.0, 0.4850, 0.1896, 0.1353 }; + fluid->setBinaryCoefficients( bics ); + return fluid; } }; -template< int NC > +template< integer NC > using FlashData = std::tuple< real64 const, // pressure real64 const, // temperature @@ -59,13 +83,13 @@ using FlashData = std::tuple< real64 const // power to raise k-values >; -template< int NC, EquationOfStateType EOS_TYPE > +template< integer NC, EquationOfStateType EOS_TYPE > class StabilityTestJacobianTestFixture : public ::testing::TestWithParam< FlashData< NC > > { static constexpr real64 relTol = 1.0e-5; static constexpr real64 absTol = 1.0e-7; - static constexpr int numComps = NC; - static constexpr int numDofs = NC + 2; + static constexpr integer numComps = NC; + static constexpr integer numDofs = NC + 2; using Deriv = geos::constitutive::multifluid::DerivativeOffset; public: StabilityTestJacobianTestFixture() @@ -78,11 +102,18 @@ class StabilityTestJacobianTestFixture : public ::testing::TestWithParam< Flash { auto componentProperties = this->m_fluid->createKernelWrapper(); - EquationOfStateType const equationOfState = EOS_TYPE; + EquationOfStateType constexpr equationOfState = EOS_TYPE; constitutive::compositional::FlashData flashData; flashData.liquidEos = equationOfState; - flashData.vapourEos = equationOfState; + if constexpr (equationOfState == EquationOfStateType::SoreideWhitson) + { + flashData.vapourEos = EquationOfStateType::PengRobinson; + } + else + { + flashData.vapourEos = equationOfState; + } real64 const pressure = std::get< 0 >( data ); real64 const temperature = std::get< 1 >( data ); @@ -120,11 +151,24 @@ class StabilityTestJacobianTestFixture : public ::testing::TestWithParam< Flash calculatePresentComponents( numComps, composition.toSliceConst(), nonZeroComponents ); auto presentComponents = nonZeroComponents.toSliceConst(); - KValueInitialization::computeWilsonGasLiquidKvalue( numComps, - pressure, - temperature, - componentProperties, - kValues ); + if constexpr (equationOfState == EquationOfStateType::SoreideWhitson) + { + KValueInitialization::computeWilsonGasLiquidKvalue( numComps, + pressure, + temperature, + componentProperties, + kValues ); + } + else + { + KValueInitialization::computeSoreideWhitsonKvalue( numComps, + pressure, + temperature, + componentProperties, + composition.toSliceConst(), + kValues ); + } + for( integer const ic: presentComponents ) { real64 const logK = LvArray::math::log( kValues[ic] ); @@ -148,16 +192,7 @@ class StabilityTestJacobianTestFixture : public ::testing::TestWithParam< Flash residual, jacobian ); - std::cout << "RESIDUAL " << std::scientific << std::setprecision( 5 ) << residual << "\n"; - std::cout << "RESIDUAL " << std::scientific << std::setprecision( 5 ) << displacedResidual << "\n"; - std::cout << "JACOBIAN\n"; - for( integer kc = 0; kc < numComps; ++kc ) - { - std::cout << " " << jacobian[kc] << "\n"; - } - std::cout << "=============================================\n"; - - // k-value derivatives + // composition derivatives // Derivatives are wrt to log(Y) real64 constexpr deltaLogY = 1.0e-3; for( integer kc = 0; kc < numComps; ++kc ) @@ -168,7 +203,7 @@ class StabilityTestJacobianTestFixture : public ::testing::TestWithParam< Flash [&]( real64 const dY, auto & values ) { LvArray::forValuesInSlice( displacedResidual, setZero ); - real64 const kvOld = logTestComposition[kc]; + real64 const logYOld = logTestComposition[kc]; logTestComposition[kc] += dY; StabilityTest::calculateResidual( numComps, presentComponents, @@ -186,7 +221,7 @@ class StabilityTestJacobianTestFixture : public ::testing::TestWithParam< Flash { values[ic] = displacedResidual[ic]; } - logTestComposition[kc] = kvOld; + logTestComposition[kc] = logYOld; } ); } } @@ -196,46 +231,60 @@ class StabilityTestJacobianTestFixture : public ::testing::TestWithParam< Flash }; using PengRobinson4 = StabilityTestJacobianTestFixture< 4, EquationOfStateType::PengRobinson >; -//using SoreideWhitson4 = StabilityTestJacobianTestFixture< 4, EquationOfStateType::SoreideWhitson >; +using SoreideWhitson4 = StabilityTestJacobianTestFixture< 4, EquationOfStateType::SoreideWhitson >; +using SoaveRedlichKwong2 = StabilityTestJacobianTestFixture< 2, EquationOfStateType::SoaveRedlichKwong >; TEST_P( PengRobinson4, testJacobian ) { testJacobian( GetParam() ); } -//TEST_P( SoreideWhitson4, testJacobian ) -//{ -// testJacobian( GetParam() ); -//} +TEST_P( SoreideWhitson4, testJacobian ) +{ + testJacobian( GetParam() ); +} + +TEST_P( SoaveRedlichKwong2, testJacobian ) +{ + testJacobian( GetParam() ); +} //------------------------------------------------------------------------------- // Data //------------------------------------------------------------------------------- -/* UNCRUSTIFY-OFF */ +template< integer NC > +stdVector< FlashData< NC > > generateData() +{ + constexpr integer dataSize = static_cast< integer >(FluidData< NC >::testCompositions.size()); + integer constexpr numSamples = dataSize / NC; + static_assert( numSamples * NC == dataSize ); -INSTANTIATE_TEST_SUITE_P(StabilityTestJacobian, PengRobinson4, - ::testing::ValuesIn>({ - {1.0e+07, 193.15, {0.3, 0.2, 0.2, 0.3}, 0.0} -// {1.0e+07, 193.15, {0.3, 0.2, 0.2, 0.3}, 1.0}, -// {1.0e+07, 193.15, {0.3, 0.2, 0.2, 0.3}, -1.0}, -// {1.0e+07, 193.15, {0.0, 0.2, 0.0, 0.8}, -1.0} - }) -); + stdVector< FlashData< NC > > data; + for( integer sampleIndex = 0; sampleIndex < numSamples; sampleIndex++ ) + { + Feed< NC > sample; + for( integer ic = 0; ic < NC; ic++ ) + { + sample[ic] = FluidData< NC >::testCompositions[sampleIndex*NC + ic]; + } + for( real64 const p : {1.0, 50.0, 100.0, 500.0} ) // Pressure in bars + { + for( real64 const t : {10.0, 25.0, 80.0, 150.0} ) // Temperature in C + { + for( real64 const a : {-1.0, 0.0, 1.0} ) + { + data.emplace_back( 1.0e5*p, t + 273.15, sample, a ); + } + } + } + } + return data; +} -/* -INSTANTIATE_TEST_SUITE_P(StabilityTestJacobian, SoreideWhitson4, - ::testing::ValuesIn>({ - {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 0.0}, - {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 0.5}, - {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 1.0}, - {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 0.998}, - {1.00000e+06, 193.15, {0.0, 0.0, 0.0, 1.0}, 1.002} - }) -); -*/ - -/* UNCRUSTIFY-ON */ +INSTANTIATE_TEST_SUITE_P( StabilityTestJacobian, PengRobinson4, ::testing::ValuesIn( generateData< 4 >()) ); +INSTANTIATE_TEST_SUITE_P( StabilityTestJacobian, SoreideWhitson4, ::testing::ValuesIn( generateData< 4 >()) ); +INSTANTIATE_TEST_SUITE_P( StabilityTestJacobian, SoaveRedlichKwong2, ::testing::ValuesIn( generateData< 2 >()) ); } // testing } // geos