From 0c898691f71d5c13c8df0347ccd1ea05d4171b98 Mon Sep 17 00:00:00 2001 From: dkachuma Date: Fri, 5 Jul 2024 12:39:58 -0500 Subject: [PATCH] Add component selector --- .../multifluid/CO2Brine/CO2BrineFluid.cpp | 8 -- .../multifluid/CO2Brine/CO2BrineFluid.hpp | 11 +- .../fluid/multifluid/MultiFluidSelector.hpp | 97 +++++++++++++++ .../multifluid/blackOil/BlackOilFluid.hpp | 2 + .../multifluid/blackOil/DeadOilFluid.hpp | 2 + .../CompositionalMultiphaseFluid.hpp | 2 + ...CompositionalMultiphaseFluidPVTPackage.hpp | 2 + .../constitutive/unitTests/CMakeLists.txt | 1 + .../unitTests/testMultiFluidSelector.cpp | 110 ++++++++++++++++++ 9 files changed, 226 insertions(+), 9 deletions(-) create mode 100644 src/coreComponents/constitutive/unitTests/testMultiFluidSelector.cpp diff --git a/src/coreComponents/constitutive/fluid/multifluid/CO2Brine/CO2BrineFluid.cpp b/src/coreComponents/constitutive/fluid/multifluid/CO2Brine/CO2BrineFluid.cpp index 87cbcdcec4c..6c0d9c2e992 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/CO2Brine/CO2BrineFluid.cpp +++ b/src/coreComponents/constitutive/fluid/multifluid/CO2Brine/CO2BrineFluid.cpp @@ -114,14 +114,6 @@ CO2BrineFluid( string const & name, Group * const parent ): } } -template< typename PHASE1, typename PHASE2, typename FLASH > -bool CO2BrineFluid< PHASE1, PHASE2, FLASH >::isThermal() const -{ - return ( PHASE1::Enthalpy::catalogName() != PVTProps::NoOpPVTFunction::catalogName() && - PHASE2::Enthalpy::catalogName() != PVTProps::NoOpPVTFunction::catalogName() ); -} - - template< typename PHASE1, typename PHASE2, typename FLASH > std::unique_ptr< ConstitutiveBase > CO2BrineFluid< PHASE1, PHASE2, FLASH >:: diff --git a/src/coreComponents/constitutive/fluid/multifluid/CO2Brine/CO2BrineFluid.hpp b/src/coreComponents/constitutive/fluid/multifluid/CO2Brine/CO2BrineFluid.hpp index 612d01e1fc3..28efbf818d2 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/CO2Brine/CO2BrineFluid.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/CO2Brine/CO2BrineFluid.hpp @@ -62,7 +62,16 @@ class CO2BrineFluid : public MultiFluidBase virtual string getCatalogName() const override { return catalogName(); } - virtual bool isThermal() const override; + static constexpr bool thermal() + { + return !( std::is_same< typename PHASE1::Enthalpy, PVTProps::NoOpPVTFunction >::value || + std::is_same< typename PHASE2::Enthalpy, PVTProps::NoOpPVTFunction >::value ); + } + + virtual bool isThermal() const override + { + return thermal(); + } /** * @brief Kernel wrapper class for CO2BrineFluid. diff --git a/src/coreComponents/constitutive/fluid/multifluid/MultiFluidSelector.hpp b/src/coreComponents/constitutive/fluid/multifluid/MultiFluidSelector.hpp index 2e1eb17f92b..590b8993696 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/MultiFluidSelector.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/MultiFluidSelector.hpp @@ -79,6 +79,103 @@ void constitutiveUpdatePassThru( MultiFluidBase & fluid, >::execute( fluid, std::forward< LAMBDA >( lambda ) ); } +namespace internal +{ +// Lists the possible numbers of components supported by a fluid type +// Most of the fluid types support only 2 components so this is the default +template< typename FluidType > +struct Components +{ + using type = camp::int_seq< integer, 2 >; +}; + +// Blackoiub fluid models support anything from 2 or 3 components +template<> +struct Components< DeadOilFluid > +{ + using type = camp::int_seq< integer, 2, 3 >; +}; +template<> +struct Components< BlackOilFluid > +{ + using type = camp::int_seq< integer, 2, 3 >; +}; + +// Compositional fluid models support anything from 2 to 5 components +template<> +struct Components< CompositionalMultiphaseFluidPVTPackage > +{ + using type = camp::int_seq< integer, 2, 3, 4, 5 >; +}; +template<> +struct Components< CompositionalTwoPhaseLohrenzBrayClarkViscosity > +{ + using type = camp::int_seq< integer, 2, 3, 4, 5 >; +}; +template<> +struct Components< CompositionalTwoPhaseConstantViscosity > +{ + using type = camp::int_seq< integer, 2, 3, 4, 5 >; +}; + +template< typename Components > +struct ComponentSelector +{}; + +template< integer ... Is > +struct ComponentSelector< camp::int_seq< integer, Is ... > > +{ + template< typename FluidType, typename LAMBDA > + static void select( int numComps, FluidType & fluid, LAMBDA && lambda ) + { + bool notSupported = false; +// With gcc8, the fold expression below issues a spurious warning +// warning: suggest parentheses around '&&' within '||' [-Wparentheses] +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94505 +#if (defined(__GNUC__) && (__GNUC__ < 10)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wparentheses" +#endif + ( ((numComps == Is) && (lambda( fluid, std::integral_constant< integer, Is >() ), true)) || ...) || (notSupported = true, false); +#if (defined(__GNUC__) && (__GNUC__ < 10)) +#pragma GCC diagnostic pop +#endif + if( notSupported ) + { + GEOS_THROW( "Unsupported number of components: " << numComps << " for fluid " << FluidType::catalogName(), SimulationError ); + } + } +}; + +} + +template< bool THERMAL = false, typename LAMBDA = NoOpFunc > +void constitutiveComponentUpdatePassThru( MultiFluidBase & fluidBase, + integer const numComps, + LAMBDA && lambda ) +{ + ConstitutivePassThruHandler< DeadOilFluid, + BlackOilFluid, +#ifdef GEOSX_USE_PVTPackage + CompositionalMultiphaseFluidPVTPackage, +#endif + CO2BrinePhillipsFluid, + CO2BrineEzrokhiFluid, + CO2BrinePhillipsThermalFluid, + CO2BrineEzrokhiThermalFluid, + CompositionalTwoPhaseLohrenzBrayClarkViscosity, + CompositionalTwoPhaseConstantViscosity + >::execute( fluidBase, [&]( auto & fluid ) + { + using FluidType = TYPEOFREF( fluid ); + if constexpr (!THERMAL || FluidType::thermal()) + { + using Components = typename internal::Components< FluidType >::type; + internal::ComponentSelector< Components >::select( numComps, fluid, std::forward< LAMBDA >( lambda )); + } + } ); +} + } // namespace constitutive } // namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/blackOil/BlackOilFluid.hpp b/src/coreComponents/constitutive/fluid/multifluid/blackOil/BlackOilFluid.hpp index 97bbc5003ee..cf2d8533497 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/blackOil/BlackOilFluid.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/blackOil/BlackOilFluid.hpp @@ -51,6 +51,8 @@ class BlackOilFluid : public BlackOilFluidBase virtual string getCatalogName() const override { return catalogName(); } + static constexpr bool thermal(){ return false; } + /** * @brief Kernel wrapper class for BlackOilFluid * This kernel can be called on the GPU diff --git a/src/coreComponents/constitutive/fluid/multifluid/blackOil/DeadOilFluid.hpp b/src/coreComponents/constitutive/fluid/multifluid/blackOil/DeadOilFluid.hpp index c651f9baf5e..ad5c7734b7c 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/blackOil/DeadOilFluid.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/blackOil/DeadOilFluid.hpp @@ -37,6 +37,8 @@ class DeadOilFluid : public BlackOilFluidBase virtual string getCatalogName() const override { return catalogName(); } + static constexpr bool thermal(){ return false; } + /** * @brief Kernel wrapper class for DeadOilFluid * This kernel can be called on the GPU diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluid.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluid.hpp index 2c077184450..4c487e96eaf 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluid.hpp @@ -67,6 +67,8 @@ class CompositionalMultiphaseFluid : public MultiFluidBase virtual string getCatalogName() const override { return catalogName(); } + static constexpr bool thermal(){ return false; } + // TODO: This method should be implemented if an incorrect extrapolation of the pressure and temperature is encountered in the kernel /** * @copydoc MultiFluidBase::checkTablesParameters( real64 pressure, real64 temperature ) diff --git a/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidPVTPackage.hpp b/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidPVTPackage.hpp index 34c08cddad6..c7fe0786618 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidPVTPackage.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/compositional/CompositionalMultiphaseFluidPVTPackage.hpp @@ -45,6 +45,8 @@ class CompositionalMultiphaseFluidPVTPackage : public MultiFluidBase virtual string getCatalogName() const override { return catalogName(); } + static constexpr bool thermal(){ return false; } + // TODO: This method should be implemented if an incorrect extrapolation of the pressure and temperature is encountered in the kernel /** * @copydoc MultiFluidBase::checkTablesParameters( real64 pressure, real64 temperature ) diff --git a/src/coreComponents/constitutive/unitTests/CMakeLists.txt b/src/coreComponents/constitutive/unitTests/CMakeLists.txt index 09f808eeb27..a4d541ee37b 100644 --- a/src/coreComponents/constitutive/unitTests/CMakeLists.txt +++ b/src/coreComponents/constitutive/unitTests/CMakeLists.txt @@ -9,6 +9,7 @@ set( gtest_geosx_tests testKValueInitialization.cpp testLohrenzBrayClarkViscosity.cpp testModifiedCamClay.cpp + testMultiFluidSelector.cpp testNegativeTwoPhaseFlash.cpp testNegativeTwoPhaseFlash9Comp.cpp testParticleFluidEnums.cpp diff --git a/src/coreComponents/constitutive/unitTests/testMultiFluidSelector.cpp b/src/coreComponents/constitutive/unitTests/testMultiFluidSelector.cpp new file mode 100644 index 00000000000..4e8363f711e --- /dev/null +++ b/src/coreComponents/constitutive/unitTests/testMultiFluidSelector.cpp @@ -0,0 +1,110 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2018-2020 TotalEnergies + * Copyright (c) 2019- 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/MultiFluidSelector.hpp" + +using namespace geos; +using namespace geos::testing; +using namespace geos::constitutive; + +template< typename FluidType > +class MultiFluidSelectorTest : public ::testing::Test +{ +public: + MultiFluidSelectorTest(): + m_node(), + m_parent( "parent", m_node ) + { + m_model = &m_parent.registerGroup< FluidType >( "fluid" ); + } + ~MultiFluidSelectorTest() override = default; + + MultiFluidBase & getFluid() const { return *m_model; } + +protected: + conduit::Node m_node; + dataRepository::Group m_parent; + FluidType * m_model{}; +}; + +using MultiFluidSelectorTestDeadOilFluid = MultiFluidSelectorTest< DeadOilFluid >; +using MultiFluidSelectorTestCO2BrinePhillipsThermalFluid = MultiFluidSelectorTest< CO2BrinePhillipsThermalFluid >; + +TEST_F( MultiFluidSelectorTestDeadOilFluid, testValidComponents ) +{ + constitutiveComponentUpdatePassThru( getFluid(), 2, []( auto &, auto NC ){ + integer constexpr numComps = NC(); + EXPECT_EQ( numComps, 2 ); + } ); + + constitutiveComponentUpdatePassThru( getFluid(), 3, []( auto &, auto NC ){ + integer constexpr numComps = NC(); + EXPECT_EQ( numComps, 3 ); + } ); +} + +TEST_F( MultiFluidSelectorTestDeadOilFluid, testInvalidComponents ) +{ + EXPECT_THROW( constitutiveComponentUpdatePassThru( getFluid(), 1, []( auto &, auto ){ + FAIL(); // Shouldn't be called + } ), SimulationError ); + + EXPECT_THROW( constitutiveComponentUpdatePassThru( getFluid(), 4, []( auto &, auto ){ + FAIL(); // Shouldn't be called + } ), SimulationError ); +} + +TEST_F( MultiFluidSelectorTestDeadOilFluid, testThermal ) +{ + constitutiveComponentUpdatePassThru< true >( getFluid(), 2, []( auto &, auto ){ + FAIL(); // Shouldn't be called + } ); +} + +TEST_F( MultiFluidSelectorTestCO2BrinePhillipsThermalFluid, testValidComponents ) +{ + constitutiveComponentUpdatePassThru( getFluid(), 2, []( auto &, auto NC ){ + integer constexpr numComps = NC(); + EXPECT_EQ( numComps, 2 ); + } ); +} + +TEST_F( MultiFluidSelectorTestCO2BrinePhillipsThermalFluid, testInvalidComponents ) +{ + EXPECT_THROW( constitutiveComponentUpdatePassThru( getFluid(), 1, []( auto &, auto ){ + FAIL(); // Shouldn't be called + } ), SimulationError ); + + EXPECT_THROW( constitutiveComponentUpdatePassThru( getFluid(), 3, []( auto &, auto ){ + FAIL(); // Shouldn't be called + } ), SimulationError ); +} + +TEST_F( MultiFluidSelectorTestCO2BrinePhillipsThermalFluid, testThermal ) +{ + bool isTested = false; + constitutiveComponentUpdatePassThru< true >( getFluid(), 2, [&]( auto &, auto ){ + isTested = true; + } ); + EXPECT_TRUE( isTested ); +} + +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + int const result = RUN_ALL_TESTS(); + return result; +}