Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
3c79271
Add Utilities class
dkachuma Jul 17, 2025
df7c29a
Add stability flash parameters
dkachuma Jul 17, 2025
39e2487
Copy file Step 1
dkachuma Jul 17, 2025
d593e70
Copy file Step 2
dkachuma Jul 17, 2025
3726f0c
Copy file Step 3
dkachuma Jul 17, 2025
d887daf
Split negative flash into 2 files
dkachuma Jul 17, 2025
7d80200
Add flash parameters
dkachuma Jul 17, 2025
d074c2d
Add stability derivatives
dkachuma Jul 18, 2025
fb5de4a
Nagative flash dervatives
dkachuma Jul 22, 2025
07353ba
Unit test
dkachuma Jul 23, 2025
548d799
Enable mass variables in compositional models
dkachuma Jul 28, 2025
01e7259
Update driver test
dkachuma Jul 28, 2025
f031fda
Merge branch 'develop' into dkachuma/compositional-mass-formulation
dkachuma Jul 28, 2025
52d5b0a
Merge branch 'develop' into dkachuma/feature/compositional-single-phase
dkachuma Jul 29, 2025
3f99c00
Use full names
dkachuma Jul 29, 2025
6a2a742
Some tests
dkachuma Jul 29, 2025
ad56448
Merge branch 'dkachuma/feature/compositional-single-phase' of https:/…
dkachuma Jul 29, 2025
e029bb7
Merge branch 'dkachuma/compositional-mass-formulation' into dkachuma/…
dkachuma Jul 29, 2025
d2a358c
Some fixes for stability test
dkachuma Jul 30, 2025
63f790e
Merge branch 'develop' into dkachuma/feature/compositional-single-phase
dkachuma Jul 30, 2025
c638068
Fix some unit tests
dkachuma Aug 1, 2025
8e394b0
Merge branch 'develop' into dkachuma/feature/compositional-single-phase
dkachuma Aug 1, 2025
27e9704
Remove debug code
dkachuma Aug 1, 2025
9df03b9
Fix unit test
dkachuma Aug 1, 2025
0f5e905
Remove debug code
dkachuma Aug 1, 2025
2607cbc
Update PVT driver test
dkachuma Aug 1, 2025
b268f8e
Update unit test
dkachuma Aug 1, 2025
0696f56
Split stability test file
dkachuma Aug 5, 2025
2a5da8f
Some more fixes
dkachuma Aug 6, 2025
1484cad
Use linear solver
dkachuma Aug 7, 2025
250ed65
Merge branch 'develop' into dkachuma/flash-newton-method
dkachuma Aug 7, 2025
141e5f5
Resolve conflicts
dkachuma Aug 7, 2025
001537d
Remove some dead code
dkachuma Aug 8, 2025
f90e5c2
Save N+1 solution
dkachuma Aug 8, 2025
c720c73
Fix Jacobian
dkachuma Aug 13, 2025
8344295
Merge branch 'develop' into dkachuma/flash-newton-method
dkachuma Oct 22, 2026
4d3bad2
Merge branch 'develop' into dkachuma/flash-newton-method
dkachuma Nov 4, 2026
ee9f529
Update stability test
dkachuma Nov 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/coreComponents/constitutive/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,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/CompositionalEnthalpy.hpp
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -113,6 +157,34 @@ 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.
*
Expand Down Expand Up @@ -157,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 );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,15 @@ class NegativeTwoPhaseFlashModelUpdate final : public FunctionBaseUpdate
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 = (pureComponent < 0) && hasZero( m_numComponents, kVapourLiquid.toSliceConst() );

if( needInitialisation )
{
if( m_flashData.liquidEos == EquationOfStateType::SoreideWhitson )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "ComponentProperties.hpp"

#include "constitutive/fluid/multifluid/MultiFluidBase.hpp"
#include "common/MpiWrapper.hpp"

namespace geos
{
Expand All @@ -39,7 +40,8 @@ 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;
m_discreteParameters[FLASH_MAX_ITERATIONS] = 300;
Expand Down Expand Up @@ -69,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] ).
Expand All @@ -81,6 +83,17 @@ 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" );

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,
Expand Down Expand Up @@ -120,6 +133,28 @@ 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() );

// 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() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand All @@ -78,7 +81,9 @@ 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"; }
static constexpr char const * negativeFlashToleranceString() { return "negativeFlashTolerance"; }
};

array1d< real64 > m_continuousParameters;
Expand Down
3 changes: 3 additions & 0 deletions src/coreComponents/constitutive/unitTests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ set( gtest_geosx_tests
testMultiFluidSelector.cpp
testNegativeTwoPhaseFlash.cpp
testNegativeTwoPhaseFlash9Comp.cpp
testNegativeTwoPhaseFlashJacobian.cpp
testNegativeTwoPhaseFlashModel.cpp
testParticleFluidEnums.cpp
testPressureTemperatureCoordinates.cpp
Expand All @@ -39,6 +40,8 @@ set( gtest_geosx_tests
testSoreideWhitsonFlash.cpp
testStabilityTest2Comp.cpp
testStabilityTest9Comp.cpp
testStabilityTestDerivatives.cpp
testStabilityTestJacobian.cpp
testRachfordRice.cpp
testTwoPhaseImmiscibleFluid.cpp )

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +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] = 100;

bool status = NegativeTwoPhaseFlash::compute(
numComps,
Expand Down
Loading
Loading