From 538e69d3b4de5446be725ee66561629278db6db9 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Thu, 13 Mar 2025 17:52:57 -0700 Subject: [PATCH 01/12] initial commit for adding the singlePhaseReactiveTransport --- .../constitutive/CMakeLists.txt | 4 + .../reactive/ReactiveFluidSelector.hpp | 15 + .../reactive/ReactiveMultiFluid.cpp | 2 +- .../reactive/ReactiveMultiFluidFields.hpp | 23 +- .../CompressibleSinglePhaseFluid.hpp | 15 + .../fluid/singlefluid/SingleFluidBase.hpp | 16 + .../fluid/singlefluid/SingleFluidSelector.hpp | 7 +- .../ThermalCompressibleSinglePhaseFluid.hpp | 15 + .../ReactiveCompressibleSinglePhaseFluid.cpp | 161 +++ .../ReactiveCompressibleSinglePhaseFluid.hpp | 290 ++++++ .../reactive/ReactiveSingleFluid.cpp | 103 ++ .../reactive/ReactiveSingleFluid.hpp | 238 +++++ .../physicsSolvers/fluidFlow/CMakeLists.txt | 8 + .../fluidFlow/SinglePhaseBase.hpp | 2 +- .../SinglePhaseReactiveTransport.cpp | 986 ++++++++++++++++++ .../SinglePhaseReactiveTransport.hpp | 276 +++++ .../SinglePhaseReactiveTransportFields.hpp | 92 ++ .../reactive/AccumulationKernels.hpp | 305 ++++++ .../reactive/FluidUpdateKernel.hpp | 58 ++ .../reactive/FluxComputeKernel.hpp | 358 +++++++ .../reactive/KernelLaunchSelectors.hpp | 73 ++ .../reactive/ResidualNormKernel.hpp | 331 ++++++ 22 files changed, 3371 insertions(+), 7 deletions(-) create mode 100644 src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.cpp create mode 100644 src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp create mode 100644 src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.cpp create mode 100644 src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluidUpdateKernel.hpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ResidualNormKernel.hpp diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index e7f798c3b5f..2a81a35e12c 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -127,6 +127,8 @@ set( constitutive_headers fluid/singlefluid/SingleFluidSelector.hpp fluid/singlefluid/SlurryFluidSelector.hpp fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp + fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp + fluid/singlefluid/reactive/ReactiveSingleFluid.hpp permeability/CarmanKozenyPermeability.hpp permeability/ConstantPermeability.hpp permeability/ExponentialDecayPermeability.hpp @@ -264,6 +266,8 @@ set( constitutive_sources fluid/singlefluid/SingleFluidBase.cpp fluid/singlefluid/SlurryFluidBase.cpp fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.cpp + fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.cpp + fluid/singlefluid/reactive/ReactiveSingleFluid.cpp permeability/CarmanKozenyPermeability.cpp permeability/ConstantPermeability.cpp permeability/ExponentialDecayPermeability.cpp diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp index 03439e9629b..d6fd9bf8ca1 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp @@ -21,6 +21,7 @@ #include "constitutive/ConstitutivePassThruHandler.hpp" #include "constitutive/fluid/multifluid/reactive/ReactiveBrineFluid.hpp" +#include "constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp" #include "common/GeosxConfig.hpp" @@ -46,6 +47,20 @@ void constitutiveUpdatePassThru( ReactiveMultiFluid & fluid, ReactiveBrineThermal >::execute( fluid, std::forward< LAMBDA >( lambda ) ); } +template< typename LAMBDA > +void constitutiveUpdatePassThru( ReactiveSingleFluid const & fluid, + LAMBDA && lambda ) +{ + ConstitutivePassThruHandler< ReactiveCompressibleSinglePhase >::execute( fluid, std::forward< LAMBDA >( lambda ) ); +} + +template< typename LAMBDA > +void constitutiveUpdatePassThru( ReactiveSingleFluid & fluid, + LAMBDA && lambda ) +{ + ConstitutivePassThruHandler< ReactiveCompressibleSinglePhase >::execute( fluid, std::forward< LAMBDA >( lambda ) ); +} + } // namespace constitutive } // namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.cpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.cpp index 09ac848a16a..a4d9deb8885 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.cpp +++ b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.cpp @@ -39,7 +39,7 @@ ReactiveMultiFluid:: registerField( fields::reactivefluid::primarySpeciesConcentration{}, &m_primarySpeciesConcentration ); registerField( fields::reactivefluid::secondarySpeciesConcentration{}, &m_secondarySpeciesConcentration ); - registerField( fields::reactivefluid::primarySpeciesTotalConcentration{}, &m_primarySpeciesTotalConcentration ); + registerField( fields::reactivefluid::primarySpeciesAggregateConcentration{}, &m_primarySpeciesTotalConcentration ); registerField( fields::reactivefluid::kineticReactionRates{}, &m_kineticReactionRates ); } diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp index d3a3a77f967..e10a004bdde 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp @@ -33,6 +33,7 @@ namespace reactivefluid { using array2dLayoutComp = array2d< real64, compflow::LAYOUT_COMP >; +using array3dLayoutComp_dC = array3d< real64, compflow::LAYOUT_COMP_DC >; DECLARE_FIELD( primarySpeciesConcentration, "primarySpeciesConcentration", @@ -42,13 +43,29 @@ DECLARE_FIELD( primarySpeciesConcentration, WRITE_AND_READ, "primarySpeciesConcentration" ); -DECLARE_FIELD( primarySpeciesTotalConcentration, - "primarySpeciesTotalConcentration", +DECLARE_FIELD( primarySpeciesAggregateConcentration, + "primarySpeciesAggregateConcentration", array2dLayoutComp, 0, LEVEL_0, WRITE_AND_READ, - "primarySpeciesTotalConcentration" ); + "primarySpeciesAggregateConcentration" ); + +DECLARE_FIELD( primarySpeciesAggregateConcentration_n, + "primarySpeciesAggregateConcentration_n", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "primarySpeciesAggregateConcentration at the previous timestep" ); + +DECLARE_FIELD( dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, + "dPrimarySpeciesAggregateConcentration_dLogPrimaryConc", + array3dLayoutComp_dC, + 0, + LEVEL_0, + WRITE_AND_READ, + "Deivatives of primarySpeciesAggregateConcentration w.r.t log primary species concentration" ); DECLARE_FIELD( secondarySpeciesConcentration, "secondarySpeciesConcentration", diff --git a/src/coreComponents/constitutive/fluid/singlefluid/CompressibleSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/singlefluid/CompressibleSinglePhaseFluid.hpp index b28f2109a21..f2c30bf2599 100644 --- a/src/coreComponents/constitutive/fluid/singlefluid/CompressibleSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/singlefluid/CompressibleSinglePhaseFluid.hpp @@ -130,6 +130,21 @@ class CompressibleSinglePhaseUpdate : public SingleFluidBaseUpdate m_dVisc_dPres[k][q] ); } + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void update( localIndex const k, + localIndex const q, + real64 const pressure, + real64 const GEOS_UNUSED_PARAM( temperature ), + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & GEOS_UNUSED_PARAM( composition ) ) const override + { + compute( pressure, + m_density[k][q], + m_dDens_dPres[k][q], + m_viscosity[k][q], + m_dVisc_dPres[k][q] ); + } + private: /// Relationship between the fluid density and pressure diff --git a/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidBase.hpp b/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidBase.hpp index d94b98672e5..b30de78c123 100644 --- a/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidBase.hpp +++ b/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidBase.hpp @@ -20,6 +20,7 @@ #ifndef GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_SINGLEFLUIDBASE_HPP #define GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_SINGLEFLUIDBASE_HPP +#include "common/DataLayouts.hpp" #include "constitutive/ConstitutiveBase.hpp" namespace geos @@ -205,6 +206,21 @@ class SingleFluidBaseUpdate real64 const pressure, real64 const temperature ) const = 0; + /** + * @brief Update fluid state at a single point. + * @param[in] k element index + * @param[in] q gauss point index + * @param[in] pressure the target pressure value + * @param[in] temperature the target temperature value + * @param[in] composition the target composition value + */ + GEOS_HOST_DEVICE + virtual void update( localIndex const k, + localIndex const q, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition ) const = 0; + }; //END_SPHINX_INCLUDE_02 diff --git a/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidSelector.hpp b/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidSelector.hpp index be6560c6c21..7f0db718d52 100644 --- a/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidSelector.hpp +++ b/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidSelector.hpp @@ -22,6 +22,7 @@ #include "constitutive/ConstitutivePassThruHandler.hpp" #include "constitutive/fluid/singlefluid/CompressibleSinglePhaseFluid.hpp" #include "constitutive/fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp" +#include "constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp" namespace geos { @@ -33,7 +34,8 @@ template< typename LAMBDA > void constitutiveUpdatePassThru( SingleFluidBase const & fluid, LAMBDA && lambda ) { - ConstitutivePassThruHandler< ThermalCompressibleSinglePhaseFluid, + ConstitutivePassThruHandler< ReactiveCompressibleSinglePhase, + ThermalCompressibleSinglePhaseFluid, CompressibleSinglePhaseFluid >::execute( fluid, std::forward< LAMBDA >( lambda ) ); } @@ -41,7 +43,8 @@ template< typename LAMBDA > void constitutiveUpdatePassThru( SingleFluidBase & fluid, LAMBDA && lambda ) { - ConstitutivePassThruHandler< ThermalCompressibleSinglePhaseFluid, + ConstitutivePassThruHandler< ReactiveCompressibleSinglePhase, + ThermalCompressibleSinglePhaseFluid, CompressibleSinglePhaseFluid >::execute( fluid, std::forward< LAMBDA >( lambda ) ); } diff --git a/src/coreComponents/constitutive/fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp index af79dd929c1..12e3c9204d4 100644 --- a/src/coreComponents/constitutive/fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp @@ -172,6 +172,21 @@ class ThermalCompressibleSinglePhaseUpdate : public SingleFluidBaseUpdate m_dEnthalpy_dTemp[k][q] ); } + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void update( localIndex const k, + localIndex const q, + real64 const pressure, + real64 const GEOS_UNUSED_PARAM( temperature ), + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & GEOS_UNUSED_PARAM( composition ) ) const override + { + compute( pressure, + m_density[k][q], + m_dDens_dPres[k][q], + m_viscosity[k][q], + m_dVisc_dPres[k][q] ); + } + private: /// Derivative of density w.r.t. temperature diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.cpp new file mode 100644 index 00000000000..266dd44c357 --- /dev/null +++ b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.cpp @@ -0,0 +1,161 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactiveCompressibleSinglePhaseFluid.cpp + */ + +#include "ReactiveCompressibleSinglePhaseFluid.hpp" + +#include "constitutive/fluid/singlefluid/SingleFluidFields.hpp" + +namespace geos +{ + +using namespace dataRepository; + +namespace constitutive +{ + +ReactiveCompressibleSinglePhase::ReactiveCompressibleSinglePhase( string const & name, Group * const parent ): + ReactiveSingleFluid( name, parent ), + m_densityModelType( ExponentApproximationType::Linear ), + m_viscosityModelType( ExponentApproximationType::Linear ) +{ + registerWrapper( viewKeyStruct::defaultDensityString(), &m_defaultDensity ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Default value for density." ); + + registerWrapper( viewKeyStruct::defaultViscosityString(), &m_defaultViscosity ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Default value for viscosity." ); + + registerWrapper( viewKeyStruct::compressibilityString(), &m_compressibility ). + setApplyDefaultValue( 0.0 ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Fluid compressibility" ); + + registerWrapper( viewKeyStruct::viscosibilityString(), &m_viscosibility ). + setApplyDefaultValue( 0.0 ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Fluid viscosity exponential coefficient" ); + + registerWrapper( viewKeyStruct::referencePressureString(), &m_referencePressure ). + setApplyDefaultValue( 0.0 ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Reference pressure" ); + + registerWrapper( viewKeyStruct::referenceDensityString(), &m_referenceDensity ). + setApplyDefaultValue( 1000.0 ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Reference fluid density" ); + + registerWrapper( viewKeyStruct::referenceViscosityString(), &m_referenceViscosity ). + setApplyDefaultValue( 0.001 ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Reference fluid viscosity" ); + + registerWrapper( viewKeyStruct::densityModelTypeString(), &m_densityModelType ). + setApplyDefaultValue( m_densityModelType ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Type of density model. Valid options:\n* " + EnumStrings< ExponentApproximationType >::concat( "\n* " ) ); + + registerWrapper( viewKeyStruct::viscosityModelTypeString(), &m_viscosityModelType ). + setApplyDefaultValue( m_viscosityModelType ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Type of viscosity model. Valid options:\n* " + EnumStrings< ExponentApproximationType >::concat( "\n* " ) ); + +} + +ReactiveCompressibleSinglePhase::~ReactiveCompressibleSinglePhase() = default; + +void ReactiveCompressibleSinglePhase::allocateConstitutiveData( dataRepository::Group & parent, + localIndex const numConstitutivePointsPerParentIndex ) +{ + ReactiveSingleFluid::allocateConstitutiveData( parent, numConstitutivePointsPerParentIndex ); + + getField< fields::singlefluid::density >().setApplyDefaultValue( m_defaultDensity ); + getField< fields::singlefluid::viscosity >().setApplyDefaultValue( m_defaultViscosity ); + + m_density.setValues< serialPolicy >( m_referenceDensity ); + m_viscosity.setValues< serialPolicy >( m_referenceViscosity ); +} + +void ReactiveCompressibleSinglePhase::postInputInitialization() +{ + ReactiveSingleFluid::postInputInitialization(); + + auto const checkNonnegative = [&]( real64 const value, auto const & attribute ) + { + GEOS_THROW_IF_LT_MSG( value, 0.0, + GEOS_FMT( "{}: invalid value of attribute '{}'", getFullName(), attribute ), + InputError ); + }; + checkNonnegative( m_compressibility, viewKeyStruct::compressibilityString() ); + checkNonnegative( m_viscosibility, viewKeyStruct::viscosibilityString() ); + + auto const checkPositive = [&]( real64 const value, auto const & attribute ) + { + GEOS_THROW_IF_LE_MSG( value, 0.0, + GEOS_FMT( "{}: invalid value of attribute '{}'", getFullName(), attribute ), + InputError ); + }; + checkPositive( m_referenceDensity, viewKeyStruct::referenceDensityString() ); + checkPositive( m_referenceViscosity, viewKeyStruct::referenceViscosityString() ); + + // Due to the way update wrapper is currently implemented, we can only support one model type + auto const checkModelType = [&]( ExponentApproximationType const value, auto const & attribute ) + { + GEOS_THROW_IF_NE_MSG( value, ExponentApproximationType::Linear, + GEOS_FMT( "{}: invalid model type in attribute '{}' (only linear currently supported)", getFullName(), attribute ), + InputError ); + }; + checkModelType( m_densityModelType, viewKeyStruct::densityModelTypeString() ); + checkModelType( m_viscosityModelType, viewKeyStruct::viscosityModelTypeString() ); + + // Set default values for derivatives (cannot be done in base class) + // TODO: reconsider the necessity of this + + real64 dRho_dP; + real64 dVisc_dP; + createKernelWrapper().compute( m_referencePressure, m_referenceDensity, dRho_dP, m_referenceViscosity, dVisc_dP ); + getField< fields::singlefluid::dDensity_dPressure >().setDefaultValue( dRho_dP ); + getField< fields::singlefluid::dViscosity_dPressure >().setDefaultValue( dVisc_dP ); +} + +ReactiveCompressibleSinglePhase::KernelWrapper +ReactiveCompressibleSinglePhase::createKernelWrapper() +{ + return KernelWrapper( KernelWrapper::DensRelationType( m_referencePressure, m_referenceDensity, m_compressibility ), + KernelWrapper::ViscRelationType( m_referencePressure, m_referenceViscosity, m_viscosibility ), + m_density, + m_dDensity_dPressure, + m_viscosity, + m_dViscosity_dPressure, + m_numPrimarySpecies, + // *m_equilibriumReactions, + // *m_kineticReactions, + m_primarySpeciesConcentration.toView(), + m_secondarySpeciesConcentration.toView(), + m_primarySpeciesAggregateConcentration.toView(), + m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc.toView(), + m_kineticReactionRates.toView() ); +} + +REGISTER_CATALOG_ENTRY( ConstitutiveBase, ReactiveCompressibleSinglePhase, string const &, Group * const ) + +} /* namespace constitutive */ + +} /* namespace geos */ diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp new file mode 100644 index 00000000000..1922d36eca6 --- /dev/null +++ b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp @@ -0,0 +1,290 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactiveCompressibleSinglePhaseFluid.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_FLUID_REACTIVECOMPRESSIBLESINGLEPHASEFLUID_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_REACTIVECOMPRESSIBLESINGLEPHASEFLUID_HPP_ + +#include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" +#include "constitutive/ExponentialRelation.hpp" + +#include + +namespace geos +{ + +namespace constitutive +{ + +/** + * @brief Update class for the model suitable for lambda capture. + * @tparam DENS_EAT type of density exponent approximation + * @tparam VISC_EAT type of viscosity exponent approximation + */ +template< ExponentApproximationType DENS_EAT, ExponentApproximationType VISC_EAT > +class ReactiveCompressibleSinglePhaseUpdate : public ReactiveSingleFluidUpdate +{ +public: + + using DensRelationType = ExponentialRelation< real64, DENS_EAT >; + using ViscRelationType = ExponentialRelation< real64, VISC_EAT >; + + ReactiveCompressibleSinglePhaseUpdate( DensRelationType const & densRelation, + ViscRelationType const & viscRelation, + arrayView2d< real64 > const & density, + arrayView2d< real64 > const & dDens_dPres, + arrayView2d< real64 > const & viscosity, + arrayView2d< real64 > const & dVisc_dPres, + integer const numPrimarySpecies, + // chemicalReactions::EquilibriumReactions const & equilibriumReactions, + // chemicalReactions::KineticReactions const & kineticReactions, + arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesConcentration, + arrayView2d< real64, compflow::USD_COMP > const & secondarySpeciesConcentration, + arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesAggregateConcentration, + arrayView3d< real64, compflow::USD_COMP_DC > const & dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, + arrayView2d< real64, compflow::USD_COMP > const & kineticReactionRates ) + : ReactiveSingleFluidUpdate( density, dDens_dPres, viscosity, dVisc_dPres, numPrimarySpecies, + // equilibriumReactions, kineticReactions, + primarySpeciesConcentration, secondarySpeciesConcentration, primarySpeciesAggregateConcentration, + dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, kineticReactionRates ), + m_densRelation( densRelation ), + m_viscRelation( viscRelation ) + {} + + /// Default copy constructor + ReactiveCompressibleSinglePhaseUpdate( ReactiveCompressibleSinglePhaseUpdate const & ) = default; + + /// Default move constructor + ReactiveCompressibleSinglePhaseUpdate( ReactiveCompressibleSinglePhaseUpdate && ) = default; + + /// Deleted copy assignment operator + ReactiveCompressibleSinglePhaseUpdate & operator=( ReactiveCompressibleSinglePhaseUpdate const & ) = delete; + + /// Deleted move assignment operator + ReactiveCompressibleSinglePhaseUpdate & operator=( ReactiveCompressibleSinglePhaseUpdate && ) = delete; + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void compute( real64 const pressure, + real64 & density, + real64 & dDensity_dPressure, + real64 & viscosity, + real64 & dViscosity_dPressure ) const override + { + m_densRelation.compute( pressure, density, dDensity_dPressure ); + m_viscRelation.compute( pressure, viscosity, dViscosity_dPressure ); + } + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void compute( real64 const pressure, + real64 const GEOS_UNUSED_PARAM( temperature ), + real64 & density, + real64 & dDensity_dPressure, + real64 & GEOS_UNUSED_PARAM( dDensity_dTemperature ), + real64 & viscosity, + real64 & dViscosity_dPressure, + real64 & GEOS_UNUSED_PARAM( dViscosity_dTemperature ), + real64 & GEOS_UNUSED_PARAM( internalEnergy ), + real64 & GEOS_UNUSED_PARAM( dInternalEnergy_dPressure ), + real64 & GEOS_UNUSED_PARAM( dInternalEnergy_dTemperature ), + real64 & GEOS_UNUSED_PARAM( enthalpy ), + real64 & GEOS_UNUSED_PARAM( dEnthalpy_dPressure ), + real64 & GEOS_UNUSED_PARAM( dEnthalpy_dTemperature ) ) const override + { + m_densRelation.compute( pressure, density, dDensity_dPressure ); + m_viscRelation.compute( pressure, viscosity, dViscosity_dPressure ); + } + + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void update( localIndex const k, + localIndex const q, + real64 const pressure ) const override + { + compute( pressure, + m_density[k][q], + m_dDens_dPres[k][q], + m_viscosity[k][q], + m_dVisc_dPres[k][q] ); + } + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void update( localIndex const k, + localIndex const q, + real64 const pressure, + real64 const GEOS_UNUSED_PARAM( temperature ) ) const override + { + compute( pressure, + m_density[k][q], + m_dDens_dPres[k][q], + m_viscosity[k][q], + m_dVisc_dPres[k][q] ); + } + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void update( localIndex const k, + localIndex const q, + real64 const pressure, + real64 const GEOS_UNUSED_PARAM( temperature ), + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & GEOS_UNUSED_PARAM( composition ) ) const override + { + compute( pressure, + m_density[k][q], + m_dDens_dPres[k][q], + m_viscosity[k][q], + m_dVisc_dPres[k][q] ); + } + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void updateChemistry( localIndex const k, + localIndex const GEOS_UNUSED_PARAM( q ), + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition ) const override + { + for( int i=0; i < m_numPrimarySpecies; i++ ) + { + m_primarySpeciesAggregateConcentration[k][i] = composition[i]; + } + + computeChemistry( pressure, + temperature, + m_primarySpeciesAggregateConcentration[k], + m_primarySpeciesConcentration[k], + m_secondarySpeciesConcentration[k], + m_kineticReactionRates[k] ); + } + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void updateChemistryLogConc( localIndex const k, + localIndex const GEOS_UNUSED_PARAM( q ), + real64 const GEOS_UNUSED_PARAM( pressure ), + real64 const GEOS_UNUSED_PARAM( temperature ), + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimaryConc ) const override + { + for( int i=0; i < m_numPrimarySpecies; i++ ) + { + m_primarySpeciesConcentration[k][i] = std::exp( logPrimaryConc[i]) ; + + m_primarySpeciesAggregateConcentration[k][i] = m_primarySpeciesConcentration[k][i]; + + m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc[k][i][i] = m_primarySpeciesConcentration[k][i]; + } + + // computeChemistry( pressure, + // temperature, + // m_primarySpeciesAggregateConcentration[k], + // m_primarySpeciesConcentration[k], + // m_secondarySpeciesConcentration[k], + // m_kineticReactionRates[k] ); + } + +private: + + /// Relationship between the fluid density and pressure + DensRelationType m_densRelation; + + /// Relationship between the fluid viscosity and pressure + ViscRelationType m_viscRelation; + +}; + +class ReactiveCompressibleSinglePhase : public ReactiveSingleFluid +{ +public: + + ReactiveCompressibleSinglePhase( string const & name, Group * const parent ); + + virtual ~ReactiveCompressibleSinglePhase() override; + + static string catalogName() { return "ReactiveCompressibleSinglePhase"; } + + virtual string getCatalogName() const override { return catalogName(); } + + virtual void allocateConstitutiveData( dataRepository::Group & parent, + localIndex const numConstitutivePointsPerParentIndex ) override; + + /// Type of kernel wrapper for in-kernel update (TODO: support multiple EAT, not just linear) + using KernelWrapper = ReactiveCompressibleSinglePhaseUpdate< ExponentApproximationType::Linear, ExponentApproximationType::Linear >; + + /** + * @brief Create an update kernel wrapper. + * @return the wrapper + */ + KernelWrapper createKernelWrapper(); + + struct viewKeyStruct + { + static constexpr char const * defaultDensityString() { return "defaultDensity"; } + static constexpr char const * defaultViscosityString() { return "defaultViscosity"; } + static constexpr char const * compressibilityString() { return "compressibility"; } + static constexpr char const * viscosibilityString() { return "viscosibility"; } + static constexpr char const * referencePressureString() { return "referencePressure"; } + static constexpr char const * referenceDensityString() { return "referenceDensity"; } + static constexpr char const * referenceViscosityString() { return "referenceViscosity"; } + static constexpr char const * densityModelTypeString() { return "densityModelType"; } + static constexpr char const * viscosityModelTypeString() { return "viscosityModelType"; } + }; + + real64 defaultDensity() const override final { return m_defaultDensity; } + real64 defaultViscosity() const override final { return m_defaultViscosity; } + +protected: + + virtual void postInputInitialization() override; + + /// default density value + real64 m_defaultDensity; + + /// default viscosity value + real64 m_defaultViscosity; + + /// scalar fluid bulk modulus parameter + real64 m_compressibility; + + /// scalar fluid viscosity exponential coefficient + real64 m_viscosibility; + + /// reference pressure parameter + real64 m_referencePressure; + + /// reference density parameter + real64 m_referenceDensity; + + /// reference viscosity parameter + real64 m_referenceViscosity; + + /// type of density model in terms of pressure + ExponentApproximationType m_densityModelType; + + /// type of viscosity model + ExponentApproximationType m_viscosityModelType; + +}; + +} /* namespace constitutive */ + +} /* namespace geos */ + +#endif /* GEOS_CONSTITUTIVE_FLUID_REACTIVECOMPRESSIBLESINGLEPHASEFLUID_HPP_ */ diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.cpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.cpp new file mode 100644 index 00000000000..ce7ffe2cbae --- /dev/null +++ b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.cpp @@ -0,0 +1,103 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactiveSingleFluid.cpp + */ +#include "ReactiveSingleFluid.hpp" + +#include "constitutive/fluid/singlefluid/SingleFluidFields.hpp" +#include "constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp" + + +namespace geos +{ + +using namespace dataRepository; + +namespace constitutive +{ + +ReactiveSingleFluid:: + ReactiveSingleFluid( string const & name, Group * const parent ): + SingleFluidBase( name, parent ) +{ + registerWrapper( viewKeyStruct::primarySpeciesNamesString(), &m_primarySpeciesNames ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "List of primary species names" ); + + // For now this is being hardcoded. We will see where this should come from. + m_numPrimarySpecies = 3; + m_numSecondarySpecies = 11; + m_numKineticReactions = 2; + + registerField( fields::reactivefluid::primarySpeciesConcentration{}, &m_primarySpeciesConcentration ); + registerField( fields::reactivefluid::secondarySpeciesConcentration{}, &m_secondarySpeciesConcentration ); + registerField( fields::reactivefluid::primarySpeciesAggregateConcentration{}, &m_primarySpeciesAggregateConcentration ); + registerField( fields::reactivefluid::primarySpeciesAggregateConcentration_n{}, &m_primarySpeciesAggregateConcentration_n ); + registerField( fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimaryConc{}, &m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc ); + registerField( fields::reactivefluid::kineticReactionRates{}, &m_kineticReactionRates ); +} + +void ReactiveSingleFluid::postInputInitialization() +{ + SingleFluidBase::postInputInitialization(); + + // // call to correctly set member array tertiary sizes on the 'main' material object + // resizeFields( 0, 0 ); + + // createChemicalReactions(); +} + +void ReactiveSingleFluid::saveConvergedState() const +{ + SingleFluidBase::saveConvergedState(); + + m_primarySpeciesAggregateConcentration_n.setValues< parallelDevicePolicy<> >( m_primarySpeciesAggregateConcentration.toViewConst() ); +} + +void ReactiveSingleFluid::resizeFields( localIndex const size, localIndex const numPts ) +{ + GEOS_UNUSED_VAR( numPts ); + + integer const numPrimarySpecies = this->numPrimarySpecies(); + integer const numSecondarySpecies = this->numSecondarySpecies(); + integer const numKineticReactions = this->numKineticReactions(); + + m_primarySpeciesConcentration.resize( size, numPrimarySpecies ); + m_secondarySpeciesConcentration.resize( size, numSecondarySpecies ); + m_primarySpeciesAggregateConcentration.resize( size, numPrimarySpecies ); + m_primarySpeciesAggregateConcentration_n.resize( size, numPrimarySpecies ); + m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc.resize( size, numPrimarySpecies, numPrimarySpecies ); + m_kineticReactionRates.resize( size, numKineticReactions ); +} + +void ReactiveSingleFluid::allocateConstitutiveData( dataRepository::Group & parent, + localIndex const numConstitutivePointsPerParentIndex ) +{ + SingleFluidBase::allocateConstitutiveData( parent, numConstitutivePointsPerParentIndex ); + resizeFields( parent.size(), numConstitutivePointsPerParentIndex ); +} + +// void ReactiveSingleFluid::createChemicalReactions() +// { +// // instantiate reactions objects +// m_equilibriumReactions = std::make_unique< chemicalReactions::EquilibriumReactions >( getName() + "_equilibriumReactions", m_numPrimarySpecies, m_numSecondarySpecies ); +// m_kineticReactions = std::make_unique< chemicalReactions::KineticReactions >( getName() + "_kineticReactions", m_numPrimarySpecies, m_numSecondarySpecies, m_numKineticReactions ); +// } + +} //namespace constitutive + +} //namespace geos diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp new file mode 100644 index 00000000000..901494d9a13 --- /dev/null +++ b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp @@ -0,0 +1,238 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactiveSingleFluid.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_REACTIVE_REACTIVESINGLEFLUID_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_REACTIVE_REACTIVESINGLEFLUID_HPP_ + + +#include "common/format/EnumStrings.hpp" +#include "constitutive/fluid/singlefluid/SingleFluidBase.hpp" +#include "constitutive/fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.hpp" +#include "constitutive/fluid/multifluid/reactive/chemicalReactions/KineticReactions.hpp" + +#include + +namespace geos +{ + +namespace constitutive +{ + +class ReactiveSingleFluidUpdate : public SingleFluidBaseUpdate +{ + public: + + GEOS_HOST_DEVICE + void computeChemistry( real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & kineticReactionRates ) const; + + GEOS_HOST_DEVICE + virtual void updateChemistry( localIndex const k, + localIndex const q, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition ) const = 0; + + GEOS_HOST_DEVICE + virtual void updateChemistryLogConc( localIndex const k, + localIndex const q, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimaryConc ) const = 0; + + protected: + + ReactiveSingleFluidUpdate( arrayView2d< real64 > const & density, + arrayView2d< real64 > const & dDens_dPres, + arrayView2d< real64 > const & viscosity, + arrayView2d< real64 > const & dVisc_dPres, + integer const numPrimarySpecies, + // chemicalReactions::EquilibriumReactions const & equilibriumReactions, + // chemicalReactions::KineticReactions const & kineticReactions, + arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesConcentration, + arrayView2d< real64, compflow::USD_COMP > const & secondarySpeciesConcentration, + arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesAggregateConcentration, + arrayView3d< real64, compflow::USD_COMP_DC > const & dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, + arrayView2d< real64, compflow::USD_COMP > const & kineticReactionRates ) + : SingleFluidBaseUpdate( density, + dDens_dPres, + viscosity, + dVisc_dPres ), + m_numPrimarySpecies( numPrimarySpecies ), + // m_equilibriumReactions( equilibriumReactions.createKernelWrapper() ), + // m_kineticReactions( kineticReactions.createKernelWrapper() ), + m_primarySpeciesConcentration( primarySpeciesConcentration ), + m_secondarySpeciesConcentration( secondarySpeciesConcentration ), + m_primarySpeciesAggregateConcentration( primarySpeciesAggregateConcentration ), + m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc( dPrimarySpeciesAggregateConcentration_dLogPrimaryConc ), + m_kineticReactionRates( kineticReactionRates ) + {} + + /** + * @brief Copy constructor. + */ + ReactiveSingleFluidUpdate( ReactiveSingleFluidUpdate const & ) = default; + + /** + * @brief Move constructor. + */ + ReactiveSingleFluidUpdate( ReactiveSingleFluidUpdate && ) = default; + + /** + * @brief Deleted copy assignment operator + * @return reference to this object + */ + ReactiveSingleFluidUpdate & operator=( ReactiveSingleFluidUpdate const & ) = delete; + + /** + * @brief Deleted move assignment operator + * @return reference to this object + */ + ReactiveSingleFluidUpdate & operator=( ReactiveSingleFluidUpdate && ) = delete; + + /// Reaction related terms + integer m_numPrimarySpecies; + + // chemicalReactions::EquilibriumReactions::KernelWrapper m_equilibriumReactions; + + // chemicalReactions::KineticReactions::KernelWrapper m_kineticReactions; + + arrayView2d< real64, compflow::USD_COMP > m_primarySpeciesConcentration; + + arrayView2d< real64, compflow::USD_COMP > m_secondarySpeciesConcentration; + + arrayView2d< real64, compflow::USD_COMP > m_primarySpeciesAggregateConcentration; + + arrayView3d< real64, compflow::USD_COMP_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; + + arrayView2d< real64, compflow::USD_COMP > m_kineticReactionRates; +}; + +class ReactiveSingleFluid : public SingleFluidBase +{ +public: + + using exec_policy = serialPolicy; + + ReactiveSingleFluid( string const & name, + Group * const parent ); + + virtual void saveConvergedState() const override; + + virtual void allocateConstitutiveData( dataRepository::Group & parent, + localIndex const numConstitutivePointsPerParentIndex ) override; + + arrayView2d< real64 const, compflow::USD_COMP > primarySpeciesConcentration() const + { return m_primarySpeciesConcentration; } + + arrayView2d< real64 const, compflow::USD_COMP > primarySpeciesAggregateConcentration() const + { return m_primarySpeciesAggregateConcentration; } + + arrayView2d< real64 const, compflow::USD_COMP > primarySpeciesAggregateConcentration_n() const + { return m_primarySpeciesAggregateConcentration_n; } + + arrayView3d< real64 const, compflow::USD_COMP_DC > dPrimarySpeciesAggregateConcentration_dLogPrimaryConc() const + { return m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; } + + arrayView2d< real64 const, compflow::USD_COMP > secondarySpeciesConcentration() const + { return m_secondarySpeciesConcentration; } + + arrayView2d< real64 const, compflow::USD_COMP > kineticReactionRates() const + { return m_kineticReactionRates; } + + integer numPrimarySpecies() const { return m_numPrimarySpecies; } + + integer numSecondarySpecies() const { return m_numSecondarySpecies; } + + integer numKineticReactions() const { return m_numKineticReactions; } + + + struct viewKeyStruct : ConstitutiveBase::viewKeyStruct + { + static constexpr char const * primarySpeciesNamesString() { return "primarySpeciesNames"; } + }; + +protected: + + virtual void postInputInitialization() override; + + void createChemicalReactions(); + + virtual void resizeFields( localIndex const size, localIndex const numPts ); + + /// Reaction related terms + array1d< string > m_primarySpeciesNames; + + integer m_numPrimarySpecies; + + integer m_numSecondarySpecies; + + integer m_numKineticReactions; + + // std::unique_ptr< chemicalReactions::EquilibriumReactions > m_equilibriumReactions; + + // std::unique_ptr< chemicalReactions::KineticReactions > m_kineticReactions; + + array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_primarySpeciesConcentration; + + array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_secondarySpeciesConcentration; + + array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_primarySpeciesAggregateConcentration; + + array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_primarySpeciesAggregateConcentration_n; + + array3d< real64, constitutive::multifluid::LAYOUT_FLUID_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; + + array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_kineticReactionRates; +}; + +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void ReactiveSingleFluidUpdate:: + computeChemistry( real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & kineticReactionRates ) const +{ + GEOS_UNUSED_VAR( pressure, temperature, primarySpeciesAggregateConcentration, primarySpeciesConcentration, secondarySpeciesConcentration, kineticReactionRates ); + + // // 2. solve for equilibrium + // m_equilibriumReactions.updateConcentrations( temperature, + // primarySpeciesAggregateConcentration, + // primarySpeciesConcentration, + // secondarySpeciesConcentration ); + + // // 3. compute kinetic reaction rates + // m_kineticReactions.computeReactionRates( temperature, + // primarySpeciesConcentration, + // secondarySpeciesConcentration, + // kineticReactionRates ); +} + +} // namespace constitutive + +} // namespace geos + +#endif //GEOS_CONSTITUTIVE_FLUID_REACTIVEMULTIFLUID_HPP diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt index 651d9135e08..66ddaf3983d 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt +++ b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt @@ -14,6 +14,8 @@ set( physicsSolvers_headers fluidFlow/SourceFluxStatistics.hpp fluidFlow/SinglePhaseBase.hpp fluidFlow/SinglePhaseBaseFields.hpp + fluidFlow/SinglePhaseReactiveTransport.hpp + fluidFlow/SinglePhaseReactiveTransportFields.hpp fluidFlow/SinglePhaseStatistics.hpp fluidFlow/SinglePhaseFVM.hpp fluidFlow/SinglePhaseHybridFVM.hpp @@ -45,6 +47,11 @@ set( physicsSolvers_headers fluidFlow/kernels/singlePhase/ThermalFluxComputeKernel.hpp fluidFlow/kernels/singlePhase/proppant/ProppantBaseKernels.hpp fluidFlow/kernels/singlePhase/proppant/ProppantFluxKernels.hpp + fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp + fluidFlow/kernels/singlePhase/reactive/FluidUpdateKernel.hpp + fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp + fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp + fluidFlow/kernels/singlePhase/reactive/ResidualNormKernel.hpp fluidFlow/kernels/compositional/AccumulationKernel.hpp fluidFlow/kernels/compositional/AquiferBCKernel.hpp fluidFlow/kernels/compositional/PPUPhaseFlux.hpp @@ -113,6 +120,7 @@ set( physicsSolvers_sources fluidFlow/ReactiveCompositionalMultiphaseOBL.cpp fluidFlow/FlowSolverBase.cpp fluidFlow/SinglePhaseBase.cpp + fluidFlow/SinglePhaseReactiveTransport.cpp fluidFlow/SinglePhaseStatistics.cpp fluidFlow/SinglePhaseFVM.cpp fluidFlow/SinglePhaseHybridFVM.cpp diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.hpp index a4049c28a87..55a14a027fe 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.hpp @@ -262,7 +262,7 @@ class SinglePhaseBase : public FlowSolverBase arrayView1d< real64 > const & localRhs ) const = 0; virtual void - updateState ( DomainPartition & domain ) override final; + updateState ( DomainPartition & domain ) override; /** * @brief Function to update all constitutive state and dependent variables diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp new file mode 100644 index 00000000000..0d337d548cc --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -0,0 +1,986 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 SinglePhaseReactiveTransport.cpp + */ + +#include "SinglePhaseReactiveTransport.hpp" + +#include "constitutive/ConstitutiveManager.hpp" +#include "constitutive/ConstitutivePassThru.hpp" +#include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" +#include "constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp" +#include "finiteVolume/FluxApproximationBase.hpp" +#include "mesh/DomainPartition.hpp" + +/** + * @namespace the geos namespace that encapsulates the majority of the code + */ +namespace geos +{ + +using namespace dataRepository; +using namespace constitutive; + +SinglePhaseReactiveTransport::SinglePhaseReactiveTransport( const string & name, + Group * const parent ): + SinglePhaseBase( name, parent ), + m_numPrimarySpecies( 0 ) +{ + // To add modeling parameters we want to add here +} + +// TODO: we need to update the class of ReactiveSingleFluid to be consistent with the chemistry module!!! +void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) +{ + using namespace fields::flow; + + SinglePhaseBase::registerDataOnMesh( meshBodies ); + + DomainPartition const & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); + ConstitutiveManager const & cm = domain.getConstitutiveManager(); + + // 0. Find a reactive fluid model name (at this point, models are already attached to subregions) + forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + if( m_reactiveFluidModelName.empty() ) + { + m_reactiveFluidModelName = getConstitutiveName< ReactiveSingleFluid >( subRegion ); + } + } ); + } ); + + // 1. Set key dimensions of the problem + // Check needed to avoid errors when running in schema generation mode. + if( !m_reactiveFluidModelName.empty() ) + { + ReactiveSingleFluid const & reactiveFluid = cm.getConstitutiveRelation< ReactiveSingleFluid >( m_reactiveFluidModelName ); + m_numPrimarySpecies = reactiveFluid.numPrimarySpecies(); + m_isThermal = reactiveFluid.isThermal(); + } + + // n_c components + one pressure ( + one temperature if needed ) + m_numDofPerCell = m_isThermal ? m_numPrimarySpecies + 2 : m_numPrimarySpecies + 1; + + // 2. Register and resize all fields as necessary (to finish) + forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + ElementRegionManager & elemManager = mesh.getElemManager(); + + elemManager.forElementSubRegions< ElementSubRegionBase >( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + subRegion.registerField< logPrimarySpeciesConcentration >( getName() ). + reference().resizeDimension< 1 >( m_numPrimarySpecies ); + + subRegion.registerField< logPrimarySpeciesConcentration_n >( getName() ). + reference().resizeDimension< 1 >( m_numPrimarySpecies ); + + subRegion.registerField< totalPrimarySpeciesAmount >( getName() ). + reference().resizeDimension< 1 >( m_numPrimarySpecies ); + + subRegion.registerField< totalPrimarySpeciesAmount_n >( getName() ). + reference().resizeDimension< 1 >( m_numPrimarySpecies ); + + subRegion.registerField< bcLogPrimarySpeciesConcentration >( getName() ). + reference().resizeDimension< 1 >( m_numPrimarySpecies ); + } ); + } ); +} + +void SinglePhaseReactiveTransport::setupDofs( DomainPartition const & domain, + DofManager & dofManager ) const +{ + // add a field for the cell-centered degrees of freedom + dofManager.addField( viewKeyStruct::elemDofFieldString(), + FieldLocation::Elem, + m_numDofPerCell, + getMeshTargets() ); + + NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); + FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); + FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + + dofManager.addCoupling( viewKeyStruct::elemDofFieldString(), fluxApprox ); +} + +void SinglePhaseReactiveTransport::resetStateToBeginningOfStep( DomainPartition & domain ) +{ + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, [&]( localIndex const, + auto & subRegion ) + { + arrayView1d< real64 > const pres = subRegion.template getField< fields::flow::pressure >(); + arrayView1d< real64 const > const pres_n = subRegion.template getField< fields::flow::pressure_n >(); + pres.setValues< parallelDevicePolicy<> >( pres_n ); + + arrayView2d< real64, compflow::USD_COMP > const logPrimarySpeciesConc = subRegion.template getField< fields::flow::logPrimarySpeciesConcentration >(); + arrayView2d< real64 const, compflow::USD_COMP > const logPrimarySpeciesConc_n = subRegion.template getField< fields::flow::logPrimarySpeciesConcentration_n >(); + logPrimarySpeciesConc.setValues< parallelDevicePolicy<> >( logPrimarySpeciesConc_n ); + + if( m_isThermal ) + { + arrayView1d< real64 > const temp = subRegion.template getField< fields::flow::temperature >(); + arrayView1d< real64 const > const temp_n = subRegion.template getField< fields::flow::temperature_n >(); + temp.setValues< parallelDevicePolicy<> >( temp_n ); + } + + updatePorosityAndPermeability( subRegion ); + updateFluidState( subRegion ); + + if( m_isThermal ) + { + updateSolidInternalEnergyModel( subRegion ); + updateEnergy( subRegion ); + } + } ); + } ); +} + +// void SinglePhaseReactiveTransport::implicitStepComplete( real64 const & time, +// real64 const & dt, +// DomainPartition & domain ) +// { + +// } + +void SinglePhaseReactiveTransport::assembleSystem( real64 const GEOS_UNUSED_PARAM( time_n ), + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) +{ + GEOS_MARK_FUNCTION; + + assembleAccumulationTermsInMassBalanceAndSpeciesAmountEqs( dt, + domain, + dofManager, + localMatrix, + localRhs ); + assembleFluxTerms( dt, + domain, + dofManager, + localMatrix, + localRhs ); +} + +void SinglePhaseReactiveTransport::assembleAccumulationTermsInMassBalanceAndSpeciesAmountEqs( real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const +{ + GEOS_MARK_FUNCTION; + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase const & subRegion ) + { + geos::constitutive::ReactiveSingleFluid const & fluid = + getConstitutiveModel< geos::constitutive::ReactiveSingleFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ) ); + geos::constitutive::CoupledSolidBase const & solid = + getConstitutiveModel< geos::constitutive::CoupledSolidBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ) ); + + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + if( m_isThermal ) + { + singlePhaseReactiveBaseKernels:: + AccumulationKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, + dt, + dofManager.rankOffset(), + dofKey, + subRegion, + fluid, + solid, + localMatrix, + localRhs ); + } + else + { + singlePhaseReactiveBaseKernels:: + AccumulationKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, + dt, + dofManager.rankOffset(), + dofKey, + subRegion, + fluid, + solid, + localMatrix, + localRhs ); + } + } ); + } ); +} + +void SinglePhaseReactiveTransport::assembleFluxTerms( real64 const dt, + DomainPartition const & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) +{ + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel const & mesh, + arrayView1d< string const > const & ) + { + NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); + FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); + FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + + string const & dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + fluxApprox.forAllStencils( mesh, [&] ( auto & stencil ) + { + typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); + + if( m_isThermal ) // To implement the thermal case + { + singlePhaseReactiveFVMKernels:: + FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, + dofManager.rankOffset(), + dofKey, + getName(), + mesh.getElemManager(), + stencilWrapper, + dt, + localMatrix.toViewConstSizes(), + localRhs.toView() ); + } + else + { + singlePhaseReactiveFVMKernels:: + FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, + dofManager.rankOffset(), + dofKey, + getName(), + mesh.getElemManager(), + stencilWrapper, + dt, + localMatrix.toViewConstSizes(), + localRhs.toView() ); + } + + // To add diffusion + } ); + } ); +} + +SinglePhaseBase::FluidPropViews SinglePhaseReactiveTransport::getFluidProperties( constitutive::ConstitutiveBase const & fluid ) const +{ + ReactiveSingleFluid const & reactiveFluid = dynamicCast< ReactiveSingleFluid const & >( fluid ); + return { reactiveFluid.density(), + reactiveFluid.dDensity_dPressure(), + reactiveFluid.viscosity(), + reactiveFluid.dViscosity_dPressure(), + reactiveFluid.getField< fields::singlefluid::density >().getDefaultValue(), + reactiveFluid.getField< fields::singlefluid::viscosity >().getDefaultValue() }; +} + +void SinglePhaseReactiveTransport::updateState( DomainPartition & domain ) +{ + GEOS_MARK_FUNCTION; + + SinglePhaseBase::updateState( domain ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, [&]( localIndex const, + auto & subRegion ) + { + updateSpeciesAmount( subRegion ); + } ); + } ); +} + +void SinglePhaseReactiveTransport::updateSpeciesAmount( ElementSubRegionBase & subRegion ) const +{ + GEOS_MARK_FUNCTION; + + arrayView2d< real64, compflow::USD_COMP > const totalPrimarySpeciesAmount = subRegion.getField< fields::flow::totalPrimarySpeciesAmount >(); + arrayView2d< real64, compflow::USD_COMP > const totalPrimarySpeciesAmount_n = subRegion.getField< fields::flow::totalPrimarySpeciesAmount_n >(); + + CoupledSolidBase const & porousSolid = + getConstitutiveModel< CoupledSolidBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ) ); + arrayView2d< real64 const > const porosity = porousSolid.getPorosity(); + arrayView2d< real64 const > const porosity_n = porousSolid.getPorosity_n(); + + arrayView1d< real64 const > const volume = subRegion.getElementVolume(); + arrayView1d< real64 > const deltaVolume = subRegion.getField< fields::flow::deltaVolume >(); + + ReactiveSingleFluid & fluid = + getConstitutiveModel< ReactiveSingleFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + arrayView2d< real64 const, compflow::USD_COMP > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); + arrayView2d< real64 const, compflow::USD_COMP > const primarySpeciesAggregateConcentration_n = fluid.primarySpeciesAggregateConcentration_n(); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + for( integer is = 0; is < m_numPrimarySpecies; ++is ) + { + totalPrimarySpeciesAmount[ei][is] = porosity[ei][0] * ( volume[ei] + deltaVolume[ei] ) * primarySpeciesAggregateConcentration[ei][is]; + + if( isZero( totalPrimarySpeciesAmount_n[ei][is] ) ) + totalPrimarySpeciesAmount_n[ei][is] = porosity_n[ei][0] * volume[ei] * primarySpeciesAggregateConcentration_n[ei][is]; + } + } ); +} + +void SinglePhaseReactiveTransport::updateFluidModel( ObjectManagerBase & dataGroup ) const +{ + GEOS_MARK_FUNCTION; + + arrayView1d< real64 const > const pres = dataGroup.getField< fields::flow::pressure >(); + arrayView1d< real64 const > const temp = dataGroup.getField< fields::flow::temperature >(); + arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc = dataGroup.getField< fields::flow::logPrimarySpeciesConcentration >(); + + ReactiveSingleFluid & fluid = + getConstitutiveModel< ReactiveSingleFluid >( dataGroup, dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + + constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) + { + typename TYPEOFREF( castedFluid ) ::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); + singlePhaseReactiveBaseKernels::FluidUpdateKernel::launch( fluidWrapper, pres, temp, logPrimaryConc ); + } ); +} + +void SinglePhaseReactiveTransport::initializeFluidState( MeshLevel & mesh, arrayView1d< string const > const & regionNames ) +{ + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, [&]( localIndex const, + auto & subRegion ) + { + ReactiveSingleFluid const & fluid = + getConstitutiveModel< ReactiveSingleFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString())); + updateFluidState( subRegion ); + + // 2. save the initial density (for use in the single-phase poromechanics solver to compute the deltaBodyForce) + fluid.initializeState(); + + SinglePhaseBase::updateMass( subRegion ); + updateSpeciesAmount( subRegion ); + } ); +} + +void SinglePhaseReactiveTransport::initializePostInitialConditionsPreSubGroups() +{ + GEOS_MARK_FUNCTION; + + FlowSolverBase::initializePostInitialConditionsPreSubGroups(); + + DomainPartition & domain = this->getGroupByPath< DomainPartition >( "/Problem/domain" ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + FieldIdentifiers fieldsToBeSync; + fieldsToBeSync.addElementFields( { fields::flow::logPrimarySpeciesConcentration::key() }, + regionNames ); + + CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), false ); + } ); + + FlowSolverBase::initializeState( domain ); +} + +void SinglePhaseReactiveTransport::applyBoundaryConditions( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) +{ + GEOS_MARK_FUNCTION; + + // if( m_keepVariablesConstantDuringInitStep ) + // { + // // this function is going to force the current flow state to be constant during the time step + // // this is used when the poromechanics solver is performing the stress initialization + // // TODO: in the future, a dedicated poromechanics kernel should eliminate the flow vars to construct a reduced system + // // which will remove the need for this brittle passing aroung of flag + // keepVariablesConstantDuringInitStep( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); + // } + // else + // { + // apply pressure boundary conditions. + applyPresSpeciesDirichletBC( time_n, dt, domain, dofManager, localMatrix.toViewConstSizes(), localRhs.toView() ); + + // // apply flux boundary conditions (To finish) + // applySourceFluxBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); + + // // apply aquifer boundary conditions (To finish) + // applyAquiferBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); + // } +} + +// // To finish +// void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time, +// real64 const dt, +// DofManager const & dofManager, +// DomainPartition & domain, +// CRSMatrixView< real64, globalIndex const > const & localMatrix, +// arrayView1d< real64 > const & localRhs ) const +// { +// GEOS_MARK_FUNCTION; + +// FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + +// string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + +// // Step 1: count individual source flux boundary conditions + +// std::map< string, localIndex > bcNameToBcId; +// localIndex bcCounter = 0; + +// fsManager.forSubGroups< SourceFluxBoundaryCondition >( [&] ( SourceFluxBoundaryCondition const & bc ) +// { +// // collect all the bc names to idx +// bcNameToBcId[bc.getName()] = bcCounter; +// bcCounter++; +// } ); + +// if( bcCounter == 0 ) +// { +// return; +// } + +// // Step 2: count the set size for each source flux (each source flux may have multiple target sets) + +// array1d< globalIndex > bcAllSetsSize( bcNameToBcId.size() ); + +// computeSourceFluxSizeScalingFactor( time_n, +// dt, +// domain, +// bcNameToBcId, +// bcAllSetsSize.toView() ); + +// // Step 3: we are ready to impose the boundary condition, normalized by the set size + +// forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, +// MeshLevel & mesh, +// arrayView1d< string const > const & ) +// { +// integer const isThermal = m_isThermal; + +// fsManager.apply< ElementSubRegionBase, +// SourceFluxBoundaryCondition >( time + dt, +// mesh, +// SourceFluxBoundaryCondition::catalogName(), +// [&, isThermal]( SourceFluxBoundaryCondition const & fs, +// string const & setName, +// SortedArrayView< localIndex const > const & targetSet, +// ElementSubRegionBase & subRegion, +// string const & ) +// { +// if( fs.getLogLevel() >= 1 && m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) +// { +// globalIndex const numTargetElems = MpiWrapper::sum< globalIndex >( targetSet.size() ); +// GEOS_LOG_RANK_0( GEOS_FMT( bcLogMessage, +// getName(), time+dt, fs.getCatalogName(), fs.getName(), +// setName, subRegion.getName(), fs.getScale(), numTargetElems ) ); +// } + +// if( targetSet.size() == 0 ) +// { +// return; +// } +// if( !subRegion.hasWrapper( dofKey ) ) +// { +// if( fs.getLogLevel() >= 1 ) +// { +// GEOS_LOG_RANK( GEOS_FMT( "{}: trying to apply SourceFlux, but its targetSet named '{}' intersects with non-simulated region named '{}'.", +// getDataContext(), setName, subRegion.getName() ) ); +// } +// return; +// } + +// arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); +// arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); + +// // Step 3.1: get the values of the source boundary condition that need to be added to the rhs + +// array1d< globalIndex > dofArray( targetSet.size() ); +// array1d< real64 > rhsContributionArray( targetSet.size() ); +// arrayView1d< real64 > rhsContributionArrayView = rhsContributionArray.toView(); +// localIndex const rankOffset = dofManager.rankOffset(); + +// RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd( 0.0 ); + +// // note that the dofArray will not be used after this step (simpler to use dofNumber instead) +// fs.computeRhsContribution< FieldSpecificationAdd, +// parallelDevicePolicy<> >( targetSet.toViewConst(), +// time + dt, +// dt, +// subRegion, +// dofNumber, +// rankOffset, +// localMatrix, +// dofArray.toView(), +// rhsContributionArrayView, +// [] GEOS_HOST_DEVICE ( localIndex const ) +// { +// return 0.0; +// } ); + +// // Step 3.2: we are ready to add the right-hand side contributions, taking into account our equation layout + +// // get the normalizer +// real64 const sizeScalingFactor = bcAllSetsSize[bcNameToBcId.at( fs.getName())]; + +// if( isThermal ) +// { + +// } +// else +// { +// integer const fluidComponentId = fs.getComponent(); +// integer const numFluidSpecies = m_numPrimarySpecies; +// forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, +// targetSet, +// rankOffset, +// ghostRank, +// fluidComponentId, +// numFluidSpecies, +// dofNumber, +// rhsContributionArrayView, +// localRhs, +// massProd] GEOS_HOST_DEVICE ( localIndex const a ) +// { +// // we need to filter out ghosts here, because targetSet may contain them +// localIndex const ei = targetSet[a]; +// if( ghostRank[ei] >= 0 ) +// { +// return; +// } + +// real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here! +// massProd += rhsValue; + +// globalIndex const totalMassBalanceRow = dofNumber[ei] - rankOffset; +// globalIndex const speciesMassBalanceRow = dofNumber[ei] - rankOffset + fluidComponentId + 1; +// localRhs[totalMassBalanceRow] += rhsValue; +// } ); +// } +// } ); +// } ); +// } + +namespace +{ +char const bcLogMessage[] = + "SinglePhaseReactiveTransport {}: at time {}s, " + "the <{}> boundary condition '{}' is applied to the element set '{}' in subRegion '{}'. " + "\nThe scale of this boundary condition is {} and multiplies the value of the provided function (if any). " + "\nThe total number of target elements (including ghost elements) is {}. " + "\nNote that if this number is equal to zero for all subRegions, the boundary condition will not be applied on this element set."; +} + +void SinglePhaseReactiveTransport::applyPresSpeciesDirichletBC( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const +{ + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & ) + { + // 1. Apply pressure Dirichlet BCs, store in a separate field + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::flow::pressure::key(), fields::flow::bcPressure::key() ); + // 2. Apply primary species BC (log promary species concentration) and store them for constitutive call + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::flow::logPrimarySpeciesConcentration::key(), fields::flow::bcLogPrimarySpeciesConcentration::key() ); + // 3. Apply temperature Dirichlet BCs, store in a separate field + if( m_isThermal ) + { + applyFieldValue< ElementSubRegionBase >( time_n, dt, mesh, bcLogMessage, + fields::flow::temperature::key(), fields::flow::bcTemperature::key() ); + } + + globalIndex const rankOffset = dofManager.rankOffset(); + string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); + + // 4. Apply pressure and log primary species concentration to the system + fsManager.apply< ElementSubRegionBase >( time_n + dt, + mesh, + fields::flow::pressure::key(), + [&] ( FieldSpecificationBase const &, + string const &, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) + { + arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); + arrayView1d< globalIndex const > const dofNumber = + subRegion.getReference< array1d< globalIndex > >( dofKey ); + + // in the isothermal case, we use the reservoir temperature to enforce the boundary condition + // in the thermal case, the validation function guarantees that temperature has been provided + arrayView1d< real64 const > const bcPres = + subRegion.getReference< array1d< real64 > >( fields::flow::bcPressure::key() ); + arrayView2d< real64 const, compflow::USD_COMP > const bcLogPrimaryConc = + subRegion.getReference< array2d< real64, compflow::LAYOUT_COMP > >( fields::flow::bcLogPrimarySpeciesConcentration::key() ); + + arrayView1d< real64 const > const pres = + subRegion.getReference< array1d< real64 > >( fields::flow::pressure::key() ); + arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc = + subRegion.getReference< array2d< real64, compflow::LAYOUT_COMP > >( fields::flow::logPrimarySpeciesConcentration::key() ); + + integer const numPrimarySpecies = m_numPrimarySpecies; + forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) + { + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + globalIndex const dofIndex = dofNumber[ei]; + localIndex const localRow = dofIndex - rankOffset; + real64 rhsValue; + + // 4.1. Apply pressure value to the matrix/rhs + FieldSpecificationEqual::SpecifyFieldValue( dofIndex, + rankOffset, + localMatrix, + rhsValue, + bcPres[ei], + pres[ei] ); + localRhs[localRow] = rhsValue; + + integer const speciesDofBeginIndex = m_isThermal? 2:1; + + // 4.2. For each component, apply target global density value + for( integer is = 0; is < numPrimarySpecies; ++is ) + { + FieldSpecificationEqual::SpecifyFieldValue( dofIndex + is + speciesDofBeginIndex, + rankOffset, + localMatrix, + rhsValue, + bcLogPrimaryConc[ei][is], + logPrimaryConc[ei][is] ); + localRhs[localRow + is + speciesDofBeginIndex] = rhsValue; + } + } ); + } ); + + // 5. Apply temperature to the system + if( m_isThermal ) + { + fsManager.apply< ElementSubRegionBase >( time_n + dt, + mesh, + fields::flow::temperature::key(), + [&] ( FieldSpecificationBase const &, + string const &, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) + { + arrayView1d< integer const > const ghostRank = + subRegion.getReference< array1d< integer > >( ObjectManagerBase::viewKeyStruct::ghostRankString() ); + arrayView1d< globalIndex const > const dofNumber = + subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< real64 const > const bcTemp = + subRegion.getReference< array1d< real64 > >( fields::flow::bcTemperature::key() ); + arrayView1d< real64 const > const temp = + subRegion.getReference< array1d< real64 > >( fields::flow::temperature::key() ); + + forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) + { + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + globalIndex const dofIndex = dofNumber[ei]; + localIndex const localRow = dofIndex - rankOffset; + real64 rhsValue; + + // 4.2. Apply temperature value to the matrix/rhs + FieldSpecificationEqual::SpecifyFieldValue( dofIndex + 1, + rankOffset, + localMatrix, + rhsValue, + bcTemp[ei], + temp[ei] ); + localRhs[localRow + 1] = rhsValue; + } ); + } ); + } + } ); +} + +real64 SinglePhaseReactiveTransport::calculateResidualNorm( real64 const & GEOS_UNUSED_PARAM( time_n ), + real64 const & GEOS_UNUSED_PARAM( dt ), + DomainPartition const & domain, + DofManager const & dofManager, + arrayView1d< real64 const > const & localRhs ) +{ + GEOS_MARK_FUNCTION; + + integer constexpr numNorm = 3; // total mass balance, energy balance, and species mass balance + array1d< real64 > localResidualNorm; + array1d< real64 > localResidualNormalizer; + localResidualNorm.resize( numNorm ); + localResidualNormalizer.resize( numNorm ); + + physicsSolverBaseKernels::NormType const normType = SinglePhaseBase::getNonlinearSolverParameters().normType(); + + globalIndex const rankOffset = dofManager.rankOffset(); + string const dofKey = dofManager.getKey( SinglePhaseBase::viewKeyStruct::elemDofFieldString() ); + + this->forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, + MeshLevel const & mesh, + arrayView1d< string const > const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase const & subRegion ) + { + real64 subRegionResidualNorm[numNorm]{}; + real64 subRegionResidualNormalizer[numNorm]{}; + + // step 1: compute the norm in the subRegion + + if( m_isThermal ) + { + singlePhaseReactiveBaseKernels:: + ResidualNormKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( normType, + m_numPrimarySpecies, + rankOffset, + dofKey, + localRhs, + subRegion, + m_nonlinearSolverParameters.m_minNormalizer, + subRegionResidualNorm, + subRegionResidualNormalizer ); + } + else + { + real64 subRegionFlowResidualNorm[2]{}; + real64 subRegionFlowResidualNormalizer[2]{}; + + singlePhaseReactiveBaseKernels:: + ResidualNormKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( normType, + m_numPrimarySpecies, + rankOffset, + dofKey, + localRhs, + subRegion, + m_nonlinearSolverParameters.m_minNormalizer, + subRegionFlowResidualNorm, + subRegionFlowResidualNormalizer ); + subRegionResidualNorm[0] = subRegionFlowResidualNorm[0]; + subRegionResidualNorm[1] = subRegionFlowResidualNorm[1]; + subRegionResidualNormalizer[0] = subRegionFlowResidualNormalizer[0]; + subRegionResidualNormalizer[1] = subRegionFlowResidualNormalizer[1]; + } + + // step 2: first reduction across meshBodies/regions/subRegions + + if( normType == physicsSolverBaseKernels::NormType::Linf ) + { + physicsSolverBaseKernels::LinfResidualNormHelper:: + updateLocalNorm< numNorm >( subRegionResidualNorm, localResidualNorm ); + } + else + { + physicsSolverBaseKernels::L2ResidualNormHelper:: + updateLocalNorm< numNorm >( subRegionResidualNorm, subRegionResidualNormalizer, localResidualNorm, localResidualNormalizer ); + } + } ); + } ); + + // step 3: second reduction across MPI ranks + + real64 residualNorm = 0.0; + array1d< real64 > globalResidualNorm; + globalResidualNorm.resize( numNorm ); + if( m_isThermal ) + { + if( normType == physicsSolverBaseKernels::NormType::Linf ) + { + physicsSolverBaseKernels::LinfResidualNormHelper:: + computeGlobalNorm( localResidualNorm, globalResidualNorm ); + } + else + { + physicsSolverBaseKernels::L2ResidualNormHelper:: + computeGlobalNorm( localResidualNorm, localResidualNormalizer, globalResidualNorm ); + } + residualNorm = sqrt( globalResidualNorm[0] * globalResidualNorm[0] + globalResidualNorm[1] * globalResidualNorm[1] + globalResidualNorm[2] * globalResidualNorm[2] ); + + GEOS_LOG_LEVEL_INFO_RANK_0_NLR( logInfo::Convergence, GEOS_FMT( " ( RtotalMass RspeciesAmount ) = ( {:4.2e} {:4.2e} ) ( Renergy ) = ( {:4.2e} )", + globalResidualNorm[0], globalResidualNorm[2], globalResidualNorm[1] )); + } + else + { + if( normType == physicsSolverBaseKernels::NormType::Linf ) + { + physicsSolverBaseKernels::LinfResidualNormHelper:: + computeGlobalNorm( localResidualNorm, globalResidualNorm ); + } + else + { + physicsSolverBaseKernels::L2ResidualNormHelper:: + computeGlobalNorm( localResidualNorm, localResidualNormalizer, globalResidualNorm ); + } + residualNorm = sqrt( globalResidualNorm[0] * globalResidualNorm[0] + globalResidualNorm[1] * globalResidualNorm[1] ); + + GEOS_LOG_LEVEL_INFO_RANK_0_NLR( logInfo::Convergence, GEOS_FMT( " ( RtotalMass RspeciesAmount ) = ( {:4.2e} {:4.2e} )", + globalResidualNorm[0], globalResidualNorm[1] ) ); + } + return residualNorm; +} + +void SinglePhaseReactiveTransport::applySystemSolution( DofManager const & dofManager, + arrayView1d< real64 const > const & localSolution, + real64 const scalingFactor, + real64 const dt, + DomainPartition & domain ) +{ + GEOS_UNUSED_VAR( dt ); + + if( m_isThermal ) + { + DofManager::CompMask pressureMask( m_numDofPerCell, 0, 1 ); + DofManager::CompMask temperatureMask( m_numDofPerCell, 1, 2 ); + DofManager::CompMask speciesMask( m_numDofPerCell, 2, m_numPrimarySpecies+2 ); + + dofManager.addVectorToField( localSolution, + viewKeyStruct::elemDofFieldString(), + fields::flow::pressure::key(), + scalingFactor, + pressureMask ); + + dofManager.addVectorToField( localSolution, + viewKeyStruct::elemDofFieldString(), + fields::flow::temperature::key(), + scalingFactor, + temperatureMask ); + + dofManager.addVectorToField( localSolution, + viewKeyStruct::elemDofFieldString(), + fields::flow::logPrimarySpeciesConcentration::key(), + scalingFactor, + speciesMask ); + } + else + { + DofManager::CompMask pressureMask( m_numDofPerCell, 0, 1 ); + DofManager::CompMask speciesMask( m_numDofPerCell, 1, m_numPrimarySpecies+1 ); + + dofManager.addVectorToField( localSolution, + viewKeyStruct::elemDofFieldString(), + fields::flow::pressure::key(), + scalingFactor, + pressureMask ); + + dofManager.addVectorToField( localSolution, + viewKeyStruct::elemDofFieldString(), + fields::flow::logPrimarySpeciesConcentration::key(), + scalingFactor, + speciesMask ); + } + + this->forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, + MeshLevel & mesh, + arrayView1d< string const > const & regionNames ) + { + std::vector< string > fields{ fields::flow::pressure::key() }; + + if( m_isThermal ) + { + fields.emplace_back( fields::flow::temperature::key() ); + } + + fields.emplace_back( fields::flow::logPrimarySpeciesConcentration::key() ); + + FieldIdentifiers fieldsToBeSync; + fieldsToBeSync.addElementFields( fields, regionNames ); + + CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), true ); + } ); +} + +void SinglePhaseReactiveTransport::saveConvergedState( ElementSubRegionBase & subRegion ) const +{ + FlowSolverBase::saveConvergedState( subRegion ); + + arrayView2d< real64 const, compflow::USD_COMP > const totalPrimarySpeciesAmount = subRegion.template getField< fields::flow::totalPrimarySpeciesAmount >(); + arrayView2d< real64, compflow::USD_COMP > const totalPrimarySpeciesAmount_n = subRegion.template getField< fields::flow::totalPrimarySpeciesAmount_n >(); + totalPrimarySpeciesAmount_n.setValues< parallelDevicePolicy<> >( totalPrimarySpeciesAmount ); +} + +void SinglePhaseReactiveTransport::assembleEDFMFluxTerms( real64 const GEOS_UNUSED_PARAM( time_n ), + real64 const GEOS_UNUSED_PARAM( dt ), + DomainPartition const & GEOS_UNUSED_PARAM( domain ), + DofManager const & GEOS_UNUSED_PARAM( dofManager ), + CRSMatrixView< real64, globalIndex const > const & GEOS_UNUSED_PARAM( localMatrix ), + arrayView1d< real64 > const & GEOS_UNUSED_PARAM( localRhs ), + string const & GEOS_UNUSED_PARAM( jumpDofKey ) ) +{ + +} + +void SinglePhaseReactiveTransport::applyAquiferBC( real64 const GEOS_UNUSED_PARAM( time ), + real64 const GEOS_UNUSED_PARAM( dt ), + DomainPartition & GEOS_UNUSED_PARAM( domain ), + DofManager const & GEOS_UNUSED_PARAM( dofManager ), + CRSMatrixView< real64, globalIndex const > const & GEOS_UNUSED_PARAM( localMatrix ), + arrayView1d< real64 > const & GEOS_UNUSED_PARAM( localRhs ) ) const +{ + +} + +void SinglePhaseReactiveTransport::assembleStabilizedFluxTerms( real64 const GEOS_UNUSED_PARAM( dt ), + DomainPartition const & GEOS_UNUSED_PARAM( domain ), + DofManager const & GEOS_UNUSED_PARAM( dofManager ), + CRSMatrixView< real64, globalIndex const > const & GEOS_UNUSED_PARAM( localMatrix ), + arrayView1d< real64 > const & GEOS_UNUSED_PARAM( localRhs ) ) +{ + +} + +REGISTER_CATALOG_ENTRY( PhysicsSolverBase, SinglePhaseReactiveTransport, string const &, Group * const ) + +} /* namespace geos */ diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp new file mode 100644 index 00000000000..65459fe6fd2 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -0,0 +1,276 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 SinglePhaseReactiveTransport.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVETRANSPORT_HPP_ +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVETRANSPORT_HPP_ + +#include "fieldSpecification/FieldSpecificationManager.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseBase.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseFVM.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluidUpdateKernel.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ResidualNormKernel.hpp" +#include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" + + +namespace geos +{ + +/** + * @class SinglePhaseReactiveTransport + * + * A solver for single phase reactive transport + */ +class SinglePhaseReactiveTransport : public SinglePhaseBase +{ + +public: + + /** + * @brief main constructor for Group Objects + * @param name the name of this instantiation of Group in the repository + * @param parent the parent group of this instantiation of Group + */ + SinglePhaseReactiveTransport( const string & name, + dataRepository::Group * const parent ); + + SinglePhaseReactiveTransport() = delete; + + /// deleted copy constructor + SinglePhaseReactiveTransport( SinglePhaseReactiveTransport const & ) = delete; + + /// default move constructor + SinglePhaseReactiveTransport( SinglePhaseReactiveTransport && ) = default; + + /// deleted assignment operator + SinglePhaseReactiveTransport & operator=( SinglePhaseReactiveTransport const & ) = delete; + + /// deleted move operator + SinglePhaseReactiveTransport & operator=( SinglePhaseReactiveTransport && ) = delete; + + /** + * @brief default destructor + */ + virtual ~SinglePhaseReactiveTransport() override = default; + + /** + * @brief name of the node manager in the object catalog + * @return string that contains the catalog name to generate a new NodeManager object through the object catalog. + */ + static string catalogName() + { + return "SinglePhaseReactiveTransport"; + } + + /** + * @copydoc PhysicsSolverBase::getCatalogName() + */ + string getCatalogName() const override { return catalogName(); } + + virtual void registerDataOnMesh( dataRepository::Group & meshBodies ) override; + + virtual void + setupDofs( DomainPartition const & domain, + DofManager & dofManager ) const override; + + virtual void + assembleSystem( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) override; + + virtual void + applyBoundaryConditions( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) override; + + virtual real64 + calculateResidualNorm( real64 const & time_n, + real64 const & dt, + DomainPartition const & domain, + DofManager const & dofManager, + arrayView1d< real64 const > const & localRhs ) override; + + virtual void + applySystemSolution( DofManager const & dofManager, + arrayView1d< real64 const > const & localSolution, + real64 const scalingFactor, + real64 const dt, + DomainPartition & domain ) override; + + virtual void + resetStateToBeginningOfStep( DomainPartition & domain ) override; + + virtual void saveConvergedState( ElementSubRegionBase & subRegion ) const override final; + + virtual void + updateState ( DomainPartition & domain ) override final; + + void updateSpeciesAmount( ElementSubRegionBase & subRegion ) const; + + virtual void updateFluidModel( ObjectManagerBase & dataGroup ) const override; + + virtual void initializePostInitialConditionsPreSubGroups() override; + + virtual void initializeFluidState( MeshLevel & mesh, arrayView1d< string const > const & regionNames ) override; + + /** + * @brief assembles the accumulation terms in total mass balance and primary species amount equation for all cells + * @param dt time step + * @param domain the physical domain object + * @param dofManager degree-of-freedom manager associated with the linear system + * @param localMatrix the system matrix + * @param localRhs the system right-hand side vector + */ + void assembleAccumulationTermsInMassBalanceAndSpeciesAmountEqs( real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const; + + /** + * @brief assembles the flux terms for all cells + * @param dt time step + * @param domain the physical domain object + * @param dofManager degree-of-freedom manager associated with the linear system + * @param matrix the system matrix + * @param rhs the system right-hand side vector + */ + virtual void + assembleFluxTerms( real64 const dt, + DomainPartition const & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) override; + + /** + * @brief Function to perform the Application of Dirichlet type BC's + * @param time current time + * @param dt time step + * @param dofManager degree-of-freedom manager associated with the linear system + * @param domain the domain + * @param localMatrix local system matrix + * @param localRhs local system right-hand side vector + */ + void + applyPresSpeciesDirichletBC( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const; + + /** + * @brief Utility function that encapsulates the call to FieldSpecificationBase::applyFieldValue in BC application + * @param[in] time_n the time at the beginning of the step + * @param[in] dt the time step + * @param[in] mesh the mesh level object + * @param[in] logMessage the log message issued by the solver if the bc is called + * @param[in] fieldKey the key of the field specified in the xml file + * @param[in] boundaryFieldKey the key of the boundary field + */ + template< typename OBJECT_TYPE > + void applyFieldValue( real64 const & time_n, + real64 const & dt, + MeshLevel & mesh, + char const logMessage[], + string const fieldKey, + string const boundaryFieldKey ) const; + + virtual void + applyAquiferBC( real64 const time, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const override; + + virtual void + assembleEDFMFluxTerms( real64 const time_n, + real64 const dt, + DomainPartition const & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs, + string const & jumpDofKey ) override final; + + virtual void + assembleStabilizedFluxTerms( real64 const dt, + DomainPartition const & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) override; + +protected: + + virtual FluidPropViews getFluidProperties( constitutive::ConstitutiveBase const & fluid ) const override; + + /// the number of primary species in the fluid + integer m_numPrimarySpecies; + + /// name of the reactive fluid constitutive model + string m_reactiveFluidModelName; +}; + +template< typename OBJECT_TYPE > +void SinglePhaseReactiveTransport::applyFieldValue( real64 const & time_n, + real64 const & dt, + MeshLevel & mesh, + char const logMessage[], + string const fieldKey, + string const boundaryFieldKey ) const +{ + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + fsManager.apply< OBJECT_TYPE >( time_n + dt, + mesh, + fieldKey, + [&]( FieldSpecificationBase const & fs, + string const & setName, + SortedArrayView< localIndex const > const & lset, + OBJECT_TYPE & targetGroup, + string const & ) + { + if( fs.getLogLevel() >= 1 && m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) + { + globalIndex const numTargetElems = MpiWrapper::sum< globalIndex >( lset.size() ); + GEOS_LOG_RANK_0( GEOS_FMT( logMessage, + getName(), time_n+dt, fs.getCatalogName(), fs.getName(), + setName, targetGroup.getName(), fs.getScale(), numTargetElems ) ); + } + + // Specify the bc value of the field + fs.applyFieldValue< FieldSpecificationEqual, + parallelDevicePolicy<> >( lset, + time_n + dt, + targetGroup, + boundaryFieldKey ); + } ); +} + +} /* namespace geos */ + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVETRANSPORT_HPP_ diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp new file mode 100644 index 00000000000..96161f5b71c --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp @@ -0,0 +1,92 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 SinglePhaseReactiveTransportFields.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVETRANSPORTFIELDS_HPP_ +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVETRANSPORTFIELDS_HPP_ + +#include "mesh/MeshFields.hpp" + +namespace geos +{ +/** + * A scope for field traits. + */ +namespace fields +{ + +namespace flow +{ +using array2dLayoutComp = array2d< real64, compflow::LAYOUT_COMP >; +using array2dLayoutFluid_dC = array2d< real64, compflow::LAYOUT_FLUID_DC >; + +DECLARE_FIELD( logPrimarySpeciesConcentration, + "logPrimarySpeciesConcentration", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "Natural log of primary species concentration (molarity)" ); + +DECLARE_FIELD( logPrimarySpeciesConcentration_n, + "logPrimarySpeciesConcentration_n", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "Natural log of primary species concentration (molarity) at the previous converged time step" ); + +DECLARE_FIELD( bcLogPrimarySpeciesConcentration, + "bcLogPrimarySpeciesConcentration", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "Boundary condition for natural log of primary species concentration (molarity)" ); + +DECLARE_FIELD( totalPrimarySpeciesAmount, + "totalPrimarySpeciesAmount", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "Total amount of species (both primary and secondary) that contain the ion in the primary species (mole)" ); + +DECLARE_FIELD( totalPrimarySpeciesAmount_n, + "totalPrimarySpeciesAmount_n", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "Total amount of species (both primary and secondary) that contain the ion in the primary species (mole) at the previous converged time step" ); + +DECLARE_FIELD( dMobility_dLogPrimaryConc, + "dMobility_dLogPrimaryConc", + array2dLayoutFluid_dC, + 0, + NOPLOT, + NO_WRITE, + "Derivative of fluid mobility with respect to log of primary species concentration" ); + +} + +} + +} + +#endif // GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVETRANSPORTFIELDS_HPP_ diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp new file mode 100644 index 00000000000..f51a5a15f58 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp @@ -0,0 +1,305 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 AccumulationKernels.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_ACCUMULATIONKERNELS_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_ACCUMULATIONKERNELS_HPP + +#include "common/DataLayouts.hpp" +#include "common/DataTypes.hpp" +#include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/AccumulationKernels.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp" + +namespace geos +{ + +namespace singlePhaseReactiveBaseKernels +{ + +/******************************** AccumulationKernel ********************************/ + +/** + * @class AccumulationKernel + * @brief Define the interface for the assembly kernel in charge of accumulation + */ +template< typename SUBREGION_TYPE, integer NUM_DOF, integer NUM_SPECIES > +class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SUBREGION_TYPE, NUM_DOF > +{ + +public: + + using Base = singlePhaseBaseKernels::AccumulationKernel< SUBREGION_TYPE, NUM_DOF >; + using Base::numDof; + using Base::numEqn; + using Base::m_rankOffset; + using Base::m_dofNumber; + using Base::m_elemGhostRank; + using Base::m_volume; + using Base::m_deltaVolume; + using Base::m_porosity; + using Base::m_dPoro_dPres; + using Base::m_density; + using Base::m_dDensity_dPres; + using Base::m_localMatrix; + using Base::m_localRhs; + + /// Compile time value for the number of primary species + static constexpr integer numSpecies = NUM_SPECIES; + + /** + * @brief Constructor + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofKey the string key to retrieve the degress of freedom numbers + * @param[in] subRegion the element subregion + * @param[in] fluid the fluid model + * @param[in] solid the solid model + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + AccumulationKernel( globalIndex const rankOffset, + string const dofKey, + SUBREGION_TYPE const & subRegion, + constitutive::ReactiveSingleFluid const & fluid, + constitutive::CoupledSolidBase const & solid, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + : Base( rankOffset, dofKey, subRegion, fluid, solid, localMatrix, localRhs ), + m_dt( dt ), + // m_dDensity_dLogPrimaryConc( fluid.dDensity_dLogPrimaryConc() ), + // m_dPoro_dLogPrimaryConc( solid.getDporosity_dLogPrimaryConc() ), + m_primarySpeciesAggregateConcentration( fluid.primarySpeciesAggregateConcentration() ), + // m_dTotalPrimarySpeciesConcentration_dPres( fluid.dTotalPrimarySpeciesConcentration_dPres() ), + m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc( fluid.dPrimarySpeciesAggregateConcentration_dLogPrimaryConc() ), + m_kineticReactionRates( fluid.kineticReactionRates() ), + // m_dPrimarySpeciesTotalKineticRate_dPres( fluid.dPrimarySpeciesTotalKineticRate_dPres() ), + // m_dPrimarySpeciesTotalKineticRate_dLogPrimaryConc( fluid.dPrimarySpeciesTotalKineticRate_dLogPrimaryConc() ), + m_totalPrimarySpeciesAmount_n( subRegion.template getField< fields::flow::totalPrimarySpeciesAmount_n >() ) + {} + + /** + * @struct StackVariables + * @brief Kernel variables (dof numbers, jacobian and residual) located on the stack + */ + struct StackVariables : public Base::StackVariables + { +public: + + GEOS_HOST_DEVICE + StackVariables() + : Base::StackVariables() + {} + + using Base::StackVariables::poreVolume; + using Base::StackVariables::dPoreVolume_dPres; + using Base::StackVariables::localRow; + using Base::StackVariables::dofIndices; + using Base::StackVariables::localResidual; + using Base::StackVariables::localJacobian; + + /// Derivative of pore volume with respect to each primary species concentration + real64 dPoreVolume_dLogPrimaryConc[numSpecies]{}; + + }; + + /** + * @brief Performs the setup phase for the kernel. + * @param[in] ei the element index + * @param[in] stack the stack variables + */ + GEOS_HOST_DEVICE + void setup( localIndex const ei, + StackVariables & stack ) const + { + Base::setup( ei, stack ); + + // // is - index of the primary species + // for( integer is = 0; is < numSpecies; ++is ) + // { + // stack.dPoreVolume_dLogPrimaryConc[is] = ( m_volume[ei] + m_deltaVolume[ei] ) * m_dPoro_dLogPrimaryConc[ei][is] + // } + } + + /** + * @brief Compute the local accumulation contributions to the residual and Jacobian + * @tparam FUNC the type of the function that can be used to customize the kernel + * @param[in] ei the element index + * @param[inout] stack the stack variables + * @param[in] kernelOp the function used to customize the kernel + */ + template< typename FUNC = NoOpFunc > + GEOS_HOST_DEVICE + void computeAccumulation( localIndex const ei, + StackVariables & stack, + FUNC && kernelOp = NoOpFunc{} ) const + { + // Residual[is] += (totalPrimarySpeciesConcentration[is] * stack.poreVolume - totalPrimarySpeciesAmount_n[is]) + // - dt * m_volume * primarySpeciesKineticRate[is] // To Check: what's the unit of the kinetic rate + + Base::computeAccumulation( ei, stack ); + // Base::computeAccumulation( ei, stack, [&] () + // { + // for( integer is = 0; is < numSpecies; ++is ) + // { + // // Step 1: assemble the derivatives of the total mass equation w.r.t log of primary species concentration + // stack.localJacobian[0][is+numDof-numSpecies] = stack.poreVolume * m_dDensity_dLogPrimaryConc[ei][is] + stack.dPoreVolume_dLogPrimaryConc[is] * m_density[ei][0]; + // } + // } ); + + arraySlice2d< real64 const, compflow::USD_COMP_DC - 1 > dPrimarySpeciesAggregateConcentration_dLogPrimaryConc = m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc[ei]; + + for( integer is = 0; is < numSpecies; ++is ) + { + // Step 2: assemble the accumulation term of the species mass balance equation + // Step 2.1: residual + // Primary species amount in pore volume + stack.localResidual[is+numEqn-numSpecies] -= m_totalPrimarySpeciesAmount_n[ei][is]; + stack.localResidual[is+numEqn-numSpecies] += m_primarySpeciesAggregateConcentration[ei][is] * stack.poreVolume; + + // // Reaction term + // stack.localResidual[is+numEqn-numSpecies] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * m_primarySpeciesTotalKineticRate[is]; + + // Step 2.1: jacobian + // Drivative of primary species amount in pore volume wrt pressure + stack.localJacobian[is+numEqn-numSpecies][0] += stack.dPoreVolume_dPres * m_primarySpeciesAggregateConcentration[ei][is] + /* + stack.poreVolume * m_dTotalPrimarySpeciesConcentration_dPres[ei][is] */; + // // Derivative of reaction term wrt pressure + // stack.localJacobian[is+numEqn-numSpecies][0] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * m_dPrimarySpeciesTotalKineticRate_dPres[is]; + + // Derivative wrt log of primary species concentration + // arraySlice2d< real64 const, compflow::USD_COMP_DC - 1 > dPrimarySpeciesTotalKineticRate_dLogPrimaryConc = m_dPrimarySpeciesTotalKineticRate_dLogPrimaryConc[ei]; + + for( integer js = 0; js < numSpecies; ++js ) + { + stack.localJacobian[is+numEqn-numSpecies][js+numDof-numSpecies] += /* stack.dPoreVolume_dLogPrimaryConc[js] * m_primarySpeciesAggregateConcentration[ei][is] + + */ stack.poreVolume * dPrimarySpeciesAggregateConcentration_dLogPrimaryConc[is][js]; // To check if the permutation is consistent + + // stack.localJacobian[is+numEqn-numSpecies][js+numDof-numSpecies] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * dPrimarySpeciesTotalKineticRate_dLogPrimaryConc[is][js]; + } + } + + kernelOp(); // To add thermal dependency + } + + /** + * @brief Performs the complete phase for the kernel. + * @param[in] ei the element index + * @param[inout] stack the stack variables + */ + GEOS_HOST_DEVICE + void complete( localIndex const ei, + StackVariables & stack ) const + { + // Step 1: assemble the total mass balance equation + // - the total mass balance equations (i = 0) + Base::complete( ei, stack ); + + // Step 2: assemble the primary species amount balance equation + // - the species amount balance equations (i = numEqn-numSpecies to i = numEqn-1) + integer const beginRowSpecies = numEqn-numSpecies; + for( integer i = 0; i < numSpecies; ++i ) + { + m_localRhs[stack.localRow + beginRowSpecies + i] += stack.localResidual[beginRowSpecies+i]; + m_localMatrix.template addToRow< serialAtomic >( stack.localRow + beginRowSpecies + i, + stack.dofIndices, + stack.localJacobian[beginRowSpecies + i], + numDof ); + } + } + +protected: + + /// Time step size + real64 const m_dt; + + // // View on the derivatives of fluid density wrt log of primary species concentration + // arrayView2d< real64 const, compflow::USD_COMP > m_dDensity_dLogPrimaryConc; + + // // View on the derivatives of porosity wrt log of primary species concentration + // arrayView2d< real64 const, compflow::USD_COMP > m_dPoro_dLogPrimaryConc; + + // View on the total concentration of ions that contain the primary species + arrayView2d< real64 const, compflow::USD_COMP > m_primarySpeciesAggregateConcentration; + + // // View on the derivatives of total ion concentration for the primary species wrt pressure + // arrayView2d< real64 const, compflow::USD_COMP > m_dTotalPrimarySpeciesConcentration_dPres; + + // View on the derivatives of total ion concentration for the primary species wrt log of primary species concentration + arrayView3d< real64 const, compflow::USD_COMP_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; + + // View on the total kinetic rate of primary species from all reactions + arrayView2d< real64 const, compflow::USD_COMP > m_kineticReactionRates; + + // // View on the derivatives of total kinetic rate of primary species wrt pressure + // arrayView2d< real64 const, compflow::USD_COMP > m_dPrimarySpeciesTotalKineticRate_dPres; + + // // View on the derivatives of total kinetic rate of primary species wrt log of primary species concentration + // arrayView3d< real64 const, compflow::USD_COMP_DC > m_dPrimarySpeciesTotalKineticRate_dLogPrimaryConc; + + // View on primary species amount (moles) from previous time step + arrayView2d< real64 const, compflow::USD_COMP > m_totalPrimarySpeciesAmount_n; +}; + +/** + * @class AccumulationKernelFactory + */ +class AccumulationKernelFactory +{ +public: + + /** + * @brief Create a new kernel and launch + * @tparam POLICY the policy used in the RAJA kernel + * @param[in] numSpecies the number of primary species + * @param[in] dt time step + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofKey the string key to retrieve the degress of freedom numbers + * @param[in] subRegion the element subregion + * @param[in] fluid the fluid model + * @param[in] solid the solid model + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + template< typename POLICY, typename SUBREGION_TYPE > + static void + createAndLaunch( integer const numSpecies, + real64 const dt, + globalIndex const rankOffset, + string const dofKey, + SUBREGION_TYPE const & subRegion, + constitutive::ReactiveSingleFluid const & fluid, + constitutive::CoupledSolidBase const & solid, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + internal::kernelLaunchSelectorCompSwitch( numSpecies, [&] ( auto NS ) + { + integer constexpr NUM_SPECIES = NS(); + integer constexpr NUM_DOF = 1+NS(); + AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES > kernel( rankOffset, dofKey, subRegion, fluid, solid, dt, localMatrix, localRhs ); + AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES >::template launch< POLICY >( subRegion.size(), kernel ); + } ); + } +}; + +} // namespace singlePhaseReactiveBaseKernels + +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_ACCUMULATIONKERNELS_HPP diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluidUpdateKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluidUpdateKernel.hpp new file mode 100644 index 00000000000..e2561c89c8e --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluidUpdateKernel.hpp @@ -0,0 +1,58 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 FluidUpdateKernel.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_FLUIDUPDATEKERNEL_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_FLUIDUPDATEKERNEL_HPP + +#include "common/DataTypes.hpp" +#include "common/GEOS_RAJA_Interface.hpp" + +namespace geos +{ + +namespace singlePhaseReactiveBaseKernels +{ + +/******************************** FluidUpdateKernel ********************************/ + +struct FluidUpdateKernel +{ + template< typename FLUID_WRAPPER > + static void launch( FLUID_WRAPPER const & fluidWrapper, + arrayView1d< real64 const > const & pres, + arrayView1d< real64 const > const & temp, + arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc ) + { + forAll< parallelDevicePolicy<> >( fluidWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) + { + for( localIndex q = 0; q < fluidWrapper.numGauss(); ++q ) + { + fluidWrapper.update( k, q, pres[k], temp[k], logPrimaryConc[k] ); + + fluidWrapper.updateChemistryLogConc( k, q, pres[k], temp[k], logPrimaryConc[k] ); + } + } ); + } +}; + +} // namespace singlePhaseReactiveBaseKernels + +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_FLUIDUPDATEKERNEL_HPP diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp new file mode 100644 index 00000000000..a987fa40633 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp @@ -0,0 +1,358 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 FluxComputeKernel.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_FLUXCOMPUTEKERNEL_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_FLUXCOMPUTEKERNEL_HPP + +#include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" +#include "constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/FluxComputeKernel.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp" + + +namespace geos +{ + +namespace singlePhaseReactiveFVMKernels +{ + +/** + * @class FluxComputeKernel + * @tparam NUM_SPECIES number of fluid primary species + * @tparam NUM_DOF number of degrees of freedom + * @tparam STENCILWRAPPER the type of the stencil wrapper + * @brief Define the interface for the assembly kernel in charge of flux terms + */ +template< integer NUM_SPECIES, integer NUM_DOF, typename STENCILWRAPPER > +class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_SPECIES+1, NUM_DOF, STENCILWRAPPER > +{ +public: + + /// Compile time value for the number of primary species + static constexpr integer numSpecies = NUM_SPECIES; + + /// Number of flux support points (hard-coded for TFPA) + static constexpr integer numFluxSupportPoints = 2; + + /** + * @brief The type for element-based data. Consists entirely of ArrayView's. + * + * Can be converted from ElementRegionManager::ElementViewConstAccessor + * by calling .toView() or .toViewConst() on an accessor instance + */ + template< typename VIEWTYPE > + using ElementViewConst = ElementRegionManager::ElementViewConst< VIEWTYPE >; + + using AbstractBase = singlePhaseFVMKernels::FluxComputeKernelBase; + using DofNumberAccessor = AbstractBase::DofNumberAccessor; + using SinglePhaseFlowAccessors = AbstractBase::SinglePhaseFlowAccessors; + using SinglePhaseFluidAccessors = AbstractBase::SinglePhaseFluidAccessors; + using PermeabilityAccessors = AbstractBase::PermeabilityAccessors; + + using AbstractBase::m_dt; + using AbstractBase::m_rankOffset; + using AbstractBase::m_dofNumber; + using AbstractBase::m_gravCoef; + using AbstractBase::m_mob; + using AbstractBase::m_dens; + using AbstractBase::m_dDens_dPres; + + using Base = singlePhaseFVMKernels::FluxComputeKernel< NUM_SPECIES+1, NUM_DOF, STENCILWRAPPER >; + using Base::numDof; + using Base::numEqn; + using Base::maxNumElems; + using Base::maxNumConns; + using Base::maxStencilSize; + using Base::m_stencilWrapper; + using Base::m_seri; + using Base::m_sesri; + using Base::m_sei; + + using ReactiveSinglePhaseFlowAccessors = + StencilAccessors< fields::flow::logPrimarySpeciesConcentration, + fields::flow::dMobility_dLogPrimaryConc >; + + using ReactiveSinglePhaseFluidAccessors = + StencilMaterialAccessors< constitutive::ReactiveSingleFluid, + fields::reactivefluid::primarySpeciesAggregateConcentration, + fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimaryConc >; + + /** + * @brief Constructor for the kernel interface + * @param[in] rankOffset the offset of my MPI rank + * @param[in] stencilWrapper reference to the stencil wrapper + * @param[in] dofNumberAccessor + * @param[in] singlePhaseFlowAccessors + * @param[in] singlePhaseFluidAccessors + * @param[in] permeabilityAccessors + * @param[in] dt time step size + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + FluxComputeKernel( globalIndex const rankOffset, + STENCILWRAPPER const & stencilWrapper, + DofNumberAccessor const & dofNumberAccessor, + SinglePhaseFlowAccessors const & singlePhaseFlowAccessors, + ReactiveSinglePhaseFlowAccessors const & reactiveSinglePhaseFlowAccessors, + SinglePhaseFluidAccessors const & singlePhaseFluidAccessors, + ReactiveSinglePhaseFluidAccessors const & reactiveSinglePhaseFluidAccessors, + PermeabilityAccessors const & permeabilityAccessors, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + : Base( rankOffset, + stencilWrapper, + dofNumberAccessor, + singlePhaseFlowAccessors, + singlePhaseFluidAccessors, + permeabilityAccessors, + dt, + localMatrix, + localRhs ), + m_logPrimarySpeciesConc( reactiveSinglePhaseFlowAccessors.get( fields::flow::logPrimarySpeciesConcentration {} ) ), + m_dMob_dLogPrimaryConc( reactiveSinglePhaseFlowAccessors.get( fields::flow::dMobility_dLogPrimaryConc {} ) ), + m_primarySpeciesAggregateConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::primarySpeciesAggregateConcentration {} ) ), + m_dPrimarySpeciesAggregateConc_dLogPrimaryConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimaryConc {} ) ) + {} + + /** + * @struct StackVariables + * @brief Kernel variables (dof numbers, jacobian and residual) located on the stack + */ + struct StackVariables : public Base::StackVariables + { +public: + + /** + * @brief Constructor for the stack variables + * @param[in] size size of the stencil for this connection + * @param[in] numElems number of elements for this connection + */ + GEOS_HOST_DEVICE + StackVariables( localIndex const size, localIndex numElems ) + : Base::StackVariables( size, numElems ) + {} + + using Base::StackVariables::stencilSize; + using Base::StackVariables::numFluxElems; + using Base::StackVariables::transmissibility; + using Base::StackVariables::dTrans_dPres; + using Base::StackVariables::dofColIndices; + using Base::StackVariables::localFlux; + using Base::StackVariables::localFluxJacobian; + }; + + /** + * @brief Compute the local flux contributions to the residual and Jacobian + * @tparam FUNC the type of the function that can be used to customize the computation of the flux + * @param[in] iconn the connection index + * @param[inout] stack the stack variables + * @param[in] NoOpFunc the function used to customize the computation of the flux + */ + GEOS_HOST_DEVICE + void computeFlux( localIndex const iconn, + StackVariables & stack ) const + { + // *********************************************** + // First, we call the base computeFlux to compute: + // 1) massFlux and its derivatives, + // 2) speciesFlux and its derivatives + Base::computeFlux( iconn, stack, [&] ( localIndex const (&k)[2], + localIndex const (&seri)[2], + localIndex const (&sesri)[2], + localIndex const (&sei)[2], + localIndex const connectionIndex, + real64 const alpha, + real64 const mobility, + real64 const & potGrad, + real64 const & fluxVal, + real64 const (&dFlux_dP)[2] ) + { + GEOS_UNUSED_VAR( connectionIndex, alpha, mobility ); + // Step 1: compute the derivatives of the fluid density, potential difference, + // and the massFlux wrt log of primary species concentration (to complete) + + // Step 2: compute the speciesFlux + real64 speciesFlux[numSpecies]{}; + real64 dSpeciesFlux_dP[numFluxSupportPoints][numSpecies]{}; + real64 dSpeciesFlux_dLogConc[numFluxSupportPoints][numSpecies][numSpecies]{}; + // real64 dSpeciesFlux_dTrans[numSpecies]{}; + + // choose upstream cell + localIndex const k_up = (potGrad >= 0) ? 0 : 1; + + localIndex const er_up = seri[k_up]; + localIndex const esr_up = sesri[k_up]; + localIndex const ei_up = sei[k_up]; + + real64 const fluidDens_up = m_dens[er_up][esr_up][ei_up][0]; + real64 const dDens_dPres = m_dDens_dPres[er_up][esr_up][ei_up][0]; + + // compute species fluxes and derivatives using upstream cell composition + for( integer is = 0; is < numSpecies; ++is ) + { + real64 const totalConc_i = m_primarySpeciesAggregateConc[er_up][esr_up][ei_up][is]; + speciesFlux[is] = totalConc_i / fluidDens_up * fluxVal; + + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + dSpeciesFlux_dP[ke][is] += totalConc_i / fluidDens_up * dFlux_dP[ke]; + } + + dSpeciesFlux_dP[k_up][is] += - totalConc_i * fluxVal * dDens_dPres / (fluidDens_up * fluidDens_up); + + for( integer js = 0; js < numSpecies; ++js ) + { + real64 const dTotalConc_i_dLogConc_j = m_dPrimarySpeciesAggregateConc_dLogPrimaryConc[er_up][esr_up][ei_up][is][js]; + dSpeciesFlux_dLogConc[k_up][is][js] += dTotalConc_i_dLogConc_j / fluidDens_up * fluxVal; + } + } + + /// populate local flux vector and derivatives + for( integer is = 0; is < numSpecies; ++is ) + { + integer const eqIndex0 = k[0] * numEqn + is + 1; + integer const eqIndex1 = k[1] * numEqn + is + 1; + + stack.localFlux[eqIndex0] += m_dt * speciesFlux[is]; + stack.localFlux[eqIndex1] -= m_dt * speciesFlux[is]; + + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + localIndex const localDofIndexPres = k[ke] * numDof; + stack.localFluxJacobian[eqIndex0][localDofIndexPres] += m_dt * dSpeciesFlux_dP[ke][is]; + stack.localFluxJacobian[eqIndex1][localDofIndexPres] -= m_dt * dSpeciesFlux_dP[ke][is]; + + for( integer js = 0; js < numSpecies; ++js ) + { + localIndex const localDofIndexSpecies = localDofIndexPres + js + 1; + stack.localFluxJacobian[eqIndex0][localDofIndexSpecies] += m_dt * dSpeciesFlux_dLogConc[ke][is][js]; + stack.localFluxJacobian[eqIndex1][localDofIndexSpecies] -= m_dt * dSpeciesFlux_dLogConc[ke][is][js]; + } + } + } + } ); + } + + /** + * @brief Performs the complete phase for the kernel. + * @param[in] iconn the connection index + * @param[inout] stack the stack variables + */ + GEOS_HOST_DEVICE + void complete( localIndex const iconn, + StackVariables & stack ) const + { + // Call Base::complete to assemble the total mass balance equation + // In the lambda, add contribution to residual and jacobian into the species amount balance equation + Base::complete( iconn, stack, [&] ( integer const i, + localIndex const localRow ) + { + // The no. of fluxes is equal to the no. of equations in m_localRhs and m_localMatrix + for( integer is = 0; is < numSpecies; ++is ) + { + RAJA::atomicAdd( parallelDeviceAtomic{}, &AbstractBase::m_localRhs[localRow + is + 1], + stack.localFlux[i * numEqn + is + 1] ); + AbstractBase::m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic > + ( localRow + is + 1, + stack.dofColIndices.data(), + stack.localFluxJacobian[i * numEqn + is + 1].dataIfContiguous(), + stack.stencilSize * numDof ); + } + } ); + } + +protected: + + /// Views on log of primary species concentration + ElementViewConst< arrayView2d< real64 const, compflow::USD_COMP > > const m_logPrimarySpeciesConc; + + /// Views on derivatives of fluid mobilities + ElementViewConst< arrayView2d< real64 const, compflow::USD_FLUID_DC > > const m_dMob_dLogPrimaryConc; + + /// Views on primary species total concentration + ElementViewConst< arrayView2d< real64 const, compflow::USD_COMP > > const m_primarySpeciesAggregateConc; + + /// Views on primary species total concentration + ElementViewConst< arrayView3d< real64 const, compflow::USD_COMP_DC > > const m_dPrimarySpeciesAggregateConc_dLogPrimaryConc; +}; + +/** + * @class FluxComputeKernelFactory + */ +class FluxComputeKernelFactory +{ +public: + + /** + * @brief Create a new kernel and launch + * @tparam POLICY the policy used in the RAJA kernel + * @tparam STENCILWRAPPER the type of the stencil wrapper + * @param[in] numSpecies the number of primary species + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofKey string to get the element degrees of freedom numbers + * @param[in] solverName name of the solver (to name accessors) + * @param[in] elemManager reference to the element region manager + * @param[in] stencilWrapper reference to the stencil wrapper + * @param[in] dt time step size + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + template< typename POLICY, typename STENCILWRAPPER > + static void + createAndLaunch( integer const numSpecies, + globalIndex const rankOffset, + string const & dofKey, + string const & solverName, + ElementRegionManager const & elemManager, + STENCILWRAPPER const & stencilWrapper, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + singlePhaseReactiveBaseKernels::internal::kernelLaunchSelectorCompSwitch( numSpecies, [&]( auto NS ) + { + integer constexpr NUM_SPECIES = NS(); + integer constexpr NUM_DOF = 1+NS(); + + ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > > dofNumberAccessor = + elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); + dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); + + using KernelType = FluxComputeKernel< NUM_SPECIES, NUM_DOF, STENCILWRAPPER >; + typename KernelType::SinglePhaseFlowAccessors flowAccessors( elemManager, solverName ); + typename KernelType::ReactiveSinglePhaseFlowAccessors reactiveFlowAccessors( elemManager, solverName ); + typename KernelType::SinglePhaseFluidAccessors fluidAccessors( elemManager, solverName ); + typename KernelType::ReactiveSinglePhaseFluidAccessors reactiveFluidAccessors( elemManager, solverName ); + typename KernelType::PermeabilityAccessors permAccessors( elemManager, solverName ); + + KernelType kernel( rankOffset, stencilWrapper, dofNumberAccessor, + flowAccessors, reactiveFlowAccessors, fluidAccessors, + reactiveFluidAccessors, permAccessors, + dt, localMatrix, localRhs ); + KernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); + } ); + } +}; + +} // namespace singlePhaseReactiveFVMKernels + +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_FLUXCOMPUTEKERNEL_HPP diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp new file mode 100644 index 00000000000..a1eff26eb32 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp @@ -0,0 +1,73 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 KernelLaunchSelector.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_KERNELLAUNCHSELECTOR_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_KERNELLAUNCHSELECTOR_HPP + +#include "physicsSolvers/KernelLaunchSelectors.hpp" +#include "codingUtilities/Utilities.hpp" +#include "common/DataLayouts.hpp" +#include "common/DataTypes.hpp" +#include "common/GEOS_RAJA_Interface.hpp" + +namespace geos +{ + +namespace singlePhaseReactiveBaseKernels +{ + +/******************************** Kernel launch machinery ********************************/ + +namespace internal +{ + +template< typename T, typename LAMBDA > +void kernelLaunchSelectorCompSwitch( T value, LAMBDA && lambda ) +{ + static_assert( std::is_integral< T >::value, "kernelLaunchSelectorCompSwitch: type should be integral" ); + + switch( value ) + { + case 1: + { lambda( std::integral_constant< T, 1 >() ); return; } + case 2: + { lambda( std::integral_constant< T, 2 >() ); return; } + case 3: + { lambda( std::integral_constant< T, 3 >() ); return; } + case 4: + { lambda( std::integral_constant< T, 4 >() ); return; } + case 5: + { lambda( std::integral_constant< T, 5 >() ); return; } + case 6: + { lambda( std::integral_constant< T, 5 >() ); return; } + case 7: + { lambda( std::integral_constant< T, 5 >() ); return; } + default: + { GEOS_ERROR( "Unsupported number of primary species: " << value ); } + } +} + +} // namespace internal + +} // namespace singlePhaseReactiveBaseKernels + +} // namespace geos + + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_KERNELLAUNCHSELECTOR_HPP diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ResidualNormKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ResidualNormKernel.hpp new file mode 100644 index 00000000000..fa985d2752e --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ResidualNormKernel.hpp @@ -0,0 +1,331 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ResidualNormKernel.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_RESIDUALNORMKERNEL_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_RESIDUALNORMKERNEL_HPP + +#include "physicsSolvers/PhysicsSolverBaseKernels.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp" + +namespace geos +{ + +namespace singlePhaseReactiveBaseKernels +{ + +/******************************** ResidualNormKernel ********************************/ + +/** + * @class IsothermalResidualNormKernel + */ +class IsothermalResidualNormKernel : public physicsSolverBaseKernels::ResidualNormKernelBase< 2 > +{ +public: + + using Base = physicsSolverBaseKernels::ResidualNormKernelBase< 2 >; + using Base::m_minNormalizer; + using Base::m_rankOffset; + using Base::m_localResidual; + using Base::m_dofNumber; + + IsothermalResidualNormKernel( globalIndex const rankOffset, + arrayView1d< real64 const > const & localResidual, + arrayView1d< globalIndex const > const & dofNumber, + arrayView1d< localIndex const > const & ghostRank, + integer const numPrimarySpecies, + ElementSubRegionBase const & subRegion, + real64 const minNormalizer ) + : Base( rankOffset, + localResidual, + dofNumber, + ghostRank, + minNormalizer ), + m_numPrimarySpecies( numPrimarySpecies ), + m_mass_n( subRegion.template getField< fields::flow::mass_n >() ), + m_totalPrimarySpeciesAmount_n( subRegion.getField< fields::flow::totalPrimarySpeciesAmount_n >() ) + {} + + GEOS_HOST_DEVICE + virtual void computeLinf( localIndex const ei, + LinfStackVariables & stack ) const override + { + real64 const totalMassNormalizer = LvArray::math::max( m_minNormalizer, m_mass_n[ei] ); + + // step 1: total mass residuals + real64 const valMass = LvArray::math::abs( m_localResidual[stack.localRow] ) / totalMassNormalizer; + if( valMass > stack.localValue[0] ) + { + stack.localValue[0] = valMass; + } + + // step 2: species amount residuals + for( integer idof = 0; idof < m_numPrimarySpecies; ++idof ) + { + real64 const speciesAmountNormalizer = LvArray::math::max( m_minNormalizer, m_totalPrimarySpeciesAmount_n[ei][idof] ); + real64 const valAmount = LvArray::math::abs( m_localResidual[stack.localRow + idof + 1] ) / speciesAmountNormalizer; + if( valAmount > stack.localValue[1] ) + { + stack.localValue[1] = valAmount; + } + } + } + + GEOS_HOST_DEVICE + virtual void computeL2( localIndex const ei, + L2StackVariables & stack ) const override + { + real64 const totalMassNormalizer = LvArray::math::max( m_minNormalizer, m_mass_n[ei] ); + + // step 1: total mass residuals + stack.localValue[0] += m_localResidual[stack.localRow] * m_localResidual[stack.localRow]; + stack.localNormalizer[0] += totalMassNormalizer; + + // step 2: species amount residuals + for( integer idof = 0; idof < m_numPrimarySpecies; ++idof ) + { + real64 const speciesAmountNormalizer = LvArray::math::max( m_minNormalizer, m_totalPrimarySpeciesAmount_n[ei][idof] ); + + stack.localValue[1] += m_localResidual[stack.localRow + idof + 1] * m_localResidual[stack.localRow + idof + 1]; + stack.localNormalizer[1] += speciesAmountNormalizer; + } + } + + +protected: + + /// Number of primary species + integer const m_numPrimarySpecies; + + /// View on mass at the previous converged time step + arrayView1d< real64 const > const m_mass_n; + + // View on primary species amount (moles) from previous time step + arrayView2d< real64 const, compflow::USD_COMP > m_totalPrimarySpeciesAmount_n; + +}; + +/** + * @class ThermalResidualNormKernel + */ +class ThermalResidualNormKernel : public physicsSolverBaseKernels::ResidualNormKernelBase< 3 > +{ +public: + + using Base = physicsSolverBaseKernels::ResidualNormKernelBase< 3 >; + using Base::m_minNormalizer; + using Base::m_rankOffset; + using Base::m_localResidual; + using Base::m_dofNumber; + + ThermalResidualNormKernel( globalIndex const rankOffset, + arrayView1d< real64 const > const & localResidual, + arrayView1d< globalIndex const > const & dofNumber, + arrayView1d< localIndex const > const & ghostRank, + integer const numPrimarySpecies, + ElementSubRegionBase const & subRegion, + real64 const minNormalizer ) + : Base( rankOffset, + localResidual, + dofNumber, + ghostRank, + minNormalizer ), + m_numPrimarySpecies( numPrimarySpecies ), + m_mass_n( subRegion.template getField< fields::flow::mass_n >() ), + m_totalPrimarySpeciesAmount_n( subRegion.getField< fields::flow::totalPrimarySpeciesAmount_n >() ), + m_energy_n( subRegion.template getField< fields::flow::energy_n >() ) + {} + + GEOS_HOST_DEVICE + void computeMassEnergyNormalizers( localIndex const ei, + real64 & totalMassNormalizer, + real64 & energyNormalizer ) const + { + totalMassNormalizer = LvArray::math::max( m_minNormalizer, m_mass_n[ei] ); + energyNormalizer = LvArray::math::max( m_minNormalizer, LvArray::math::abs( m_energy_n[ei] ) ); // energy can be negative + } + + GEOS_HOST_DEVICE + virtual void computeLinf( localIndex const ei, + LinfStackVariables & stack ) const override + { + real64 totalMassNormalizer = 0.0, energyNormalizer = 0.0; + computeMassEnergyNormalizers( ei, totalMassNormalizer, energyNormalizer ); + + // step 1: mass residual + + real64 const valMass = LvArray::math::abs( m_localResidual[stack.localRow] ) / totalMassNormalizer; + if( valMass > stack.localValue[0] ) + { + stack.localValue[0] = valMass; + } + + // step 2: energy residual + real64 const valEnergy = LvArray::math::abs( m_localResidual[stack.localRow + 1] ) / energyNormalizer; + if( valEnergy > stack.localValue[1] ) + { + stack.localValue[1] = valEnergy; + } + + // step 3: species amount residuals + for( integer idof = 0; idof < m_numPrimarySpecies; ++idof ) + { + real64 const speciesAmountNormalizer = LvArray::math::max( m_minNormalizer, m_totalPrimarySpeciesAmount_n[ei][idof] ); + real64 const valAmount = LvArray::math::abs( m_localResidual[stack.localRow + idof + 2] ) / speciesAmountNormalizer; + if( valAmount > stack.localValue[2] ) + { + stack.localValue[2] = valAmount; + } + } + } + + GEOS_HOST_DEVICE + virtual void computeL2( localIndex const ei, + L2StackVariables & stack ) const override + { + real64 totalMassNormalizer = 0.0, energyNormalizer = 0.0; + computeMassEnergyNormalizers( ei, totalMassNormalizer, energyNormalizer ); + + // step 1: mass residual + + stack.localValue[0] += m_localResidual[stack.localRow] * m_localResidual[stack.localRow]; + stack.localNormalizer[0] += totalMassNormalizer; + + // step 2: energy residual + + stack.localValue[1] += m_localResidual[stack.localRow + 1] * m_localResidual[stack.localRow + 1]; + stack.localNormalizer[1] += energyNormalizer; + + // step 3: species amount residuals + for( integer idof = 0; idof < m_numPrimarySpecies; ++idof ) + { + real64 const speciesAmountNormalizer = LvArray::math::max( m_minNormalizer, m_totalPrimarySpeciesAmount_n[ei][idof] ); + + stack.localValue[2] += m_localResidual[stack.localRow + idof + 2] * m_localResidual[stack.localRow + idof + 2]; + stack.localNormalizer[2] += speciesAmountNormalizer; + } + } + + +protected: + + /// Number of primary species + integer const m_numPrimarySpecies; + + /// View on mass at the previous converged time step + arrayView1d< real64 const > const m_mass_n; + + // View on primary species amount (moles) from previous time step + arrayView2d< real64 const, compflow::USD_COMP > m_totalPrimarySpeciesAmount_n; + + /// View on energy at the previous converged time step + arrayView1d< real64 const > const m_energy_n; + +}; + +/** + * @class ResidualNormKernelFactory + */ +class ResidualNormKernelFactory +{ +public: + + /** + * @brief Create a new kernel and launch + * @tparam POLICY the policy used in the RAJA kernel + * @param[in] normType the type of norm used (Linf or L2) + * @param[in] numPrimarySpecies the number of primary species + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofKey the string key to retrieve the degress of freedom numbers + * @param[in] localResidual the residual vector on my MPI rank + * @param[in] subRegion the element subregion + * @param[out] residualNorm the residual norm on the subRegion + * @param[out] residualNormalizer the residual normalizer on the subRegion + */ + template< typename POLICY > + static void + createAndLaunch( physicsSolverBaseKernels::NormType const normType, + integer const numPrimarySpecies, + globalIndex const rankOffset, + string const dofKey, + arrayView1d< real64 const > const & localResidual, + ElementSubRegionBase const & subRegion, + real64 const minNormalizer, + real64 (& residualNorm)[2], + real64 (& residualNormalizer)[2] ) + { + arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); + + IsothermalResidualNormKernel kernel( rankOffset, localResidual, dofNumber, ghostRank, numPrimarySpecies, subRegion, minNormalizer ); + if( normType == physicsSolverBaseKernels::NormType::Linf ) + { + IsothermalResidualNormKernel::launchLinf< POLICY >( subRegion.size(), kernel, residualNorm ); + } + else // L2 norm + { + IsothermalResidualNormKernel::launchL2< POLICY >( subRegion.size(), kernel, residualNorm, residualNormalizer ); + } + } + + /** + * @brief Create a new kernel and launch (thermal version) + * @tparam POLICY the policy used in the RAJA kernel + * @param[in] normType the type of norm used (Linf or L2) + * @param[in] numPrimarySpecies the number of primary species + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofKey the string key to retrieve the degress of freedom numbers + * @param[in] localResidual the residual vector on my MPI rank + * @param[in] subRegion the element subregion + * @param[out] residualNorm the residual norm on the subRegion + * @param[out] residualNormalizer the residual normalizer on the subRegion + */ + template< typename POLICY > + static void + createAndLaunch( physicsSolverBaseKernels::NormType const normType, + integer const numPrimarySpecies, + globalIndex const rankOffset, + string const & dofKey, + arrayView1d< real64 const > const & localResidual, + ElementSubRegionBase const & subRegion, + real64 const minNormalizer, + real64 (& residualNorm)[3], + real64 (& residualNormalizer)[3] ) + { + arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey ); + arrayView1d< integer const > const ghostRank = subRegion.ghostRank(); + + ThermalResidualNormKernel kernel( rankOffset, localResidual, dofNumber, ghostRank, numPrimarySpecies, subRegion, minNormalizer ); + if( normType == physicsSolverBaseKernels::NormType::Linf ) + { + ThermalResidualNormKernel::launchLinf< POLICY >( subRegion.size(), kernel, residualNorm ); + } + else // L2 norm + { + ThermalResidualNormKernel::launchL2< POLICY >( subRegion.size(), kernel, residualNorm, residualNormalizer ); + } + } + +}; + +} // namespace singlePhaseReactiveBaseKernels + +} // namespace geos + + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_RESIDUALNORMKERNEL_HPP From 3d7586281b957015c3e17725075b3cc79dc60cc0 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Thu, 13 Mar 2025 18:12:38 -0700 Subject: [PATCH 02/12] added an 1D test --- .../ReactiveCompressible_1d.xml | 283 ++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 inputFiles/singlePhaseFlow/ReactiveCompressible_1d.xml diff --git a/inputFiles/singlePhaseFlow/ReactiveCompressible_1d.xml b/inputFiles/singlePhaseFlow/ReactiveCompressible_1d.xml new file mode 100644 index 00000000000..a9fb09731d4 --- /dev/null +++ b/inputFiles/singlePhaseFlow/ReactiveCompressible_1d.xml @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 23de93c611b3ff6a303f8a12a8c4a71dc69c3d81 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Tue, 18 Mar 2025 15:26:13 -0700 Subject: [PATCH 03/12] added diffusion --- .../SinglePhaseReactiveTransport.cpp | 68 ++++++- .../SinglePhaseReactiveTransport.hpp | 13 ++ .../reactive/FluxComputeKernel.hpp | 177 ++++++++++++++++-- 3 files changed, 240 insertions(+), 18 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 0b865eae8ba..a0154546539 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -21,6 +21,8 @@ #include "constitutive/ConstitutiveManager.hpp" #include "constitutive/ConstitutivePassThru.hpp" +#include "constitutive/diffusion/DiffusionFields.hpp" +#include "constitutive/diffusion/DiffusionSelector.hpp" #include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" #include "constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp" #include "finiteVolume/FluxApproximationBase.hpp" @@ -38,7 +40,8 @@ using namespace constitutive; SinglePhaseReactiveTransport::SinglePhaseReactiveTransport( const string & name, Group * const parent ): SinglePhaseBase( name, parent ), - m_numPrimarySpecies( 0 ) + m_numPrimarySpecies( 0 ), + m_hasDiffusion( 0 ) { // To add modeling parameters we want to add here } @@ -66,6 +69,13 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) { m_reactiveFluidModelName = getConstitutiveName< ReactiveSingleFluid >( subRegion ); } + + // If at least one region has a diffusion model, consider it enabled for all + string const diffusionName = getConstitutiveName< DiffusionBase >( subRegion ); + if( !diffusionName.empty() ) + { + m_hasDiffusion = true; + } } ); } ); @@ -92,6 +102,21 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) [&]( localIndex const, ElementSubRegionBase & subRegion ) { + if( m_hasDiffusion ) + { + subRegion.registerWrapper< string >( viewKeyStruct::diffusionNamesString() ). + setPlotLevel( PlotLevel::NOPLOT ). + setRestartFlags( RestartFlags::NO_WRITE ). + setSizedFromParent( 0 ). + setDescription( "Name of the diffusion constitutive model to use" ); + + string & diffusionName = subRegion.getReference< string >( viewKeyStruct::diffusionNamesString() ); + diffusionName = getConstitutiveName< DiffusionBase >( subRegion ); + GEOS_THROW_IF( diffusionName.empty(), + GEOS_FMT( "Diffusion model not found on subregion {}", subRegion.getName() ), + InputError ); + } + subRegion.registerField< logPrimarySpeciesConcentration >( getName() ). reference().resizeDimension< 1 >( m_numPrimarySpecies ); @@ -162,12 +187,32 @@ void SinglePhaseReactiveTransport::resetStateToBeginningOfStep( DomainPartition } ); } -// void SinglePhaseReactiveTransport::implicitStepComplete( real64 const & time, -// real64 const & dt, -// DomainPartition & domain ) -// { +void SinglePhaseReactiveTransport::implicitStepComplete( real64 const & time, + real64 const & dt, + DomainPartition & domain ) +{ + GEOS_MARK_FUNCTION; -// } + SinglePhaseBase::implicitStepComplete( time, dt, domain ); + + if( m_hasDiffusion ) + { + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + string const & diffusionName = subRegion.getReference< string >( viewKeyStruct::diffusionNamesString() ); + DiffusionBase const & diffusionMaterial = getConstitutiveModel< DiffusionBase >( subRegion, diffusionName ); + arrayView1d< real64 const > const temperature = subRegion.template getField< fields::flow::temperature >(); + diffusionMaterial.saveConvergedTemperatureState( temperature ); + } ); + } ); + } +} void SinglePhaseReactiveTransport::assembleSystem( real64 const GEOS_UNUSED_PARAM( time_n ), real64 const dt, @@ -269,6 +314,7 @@ void SinglePhaseReactiveTransport::assembleFluxTerms( real64 const dt, { singlePhaseReactiveFVMKernels:: FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, + m_hasDiffusion, dofManager.rankOffset(), dofKey, getName(), @@ -282,6 +328,7 @@ void SinglePhaseReactiveTransport::assembleFluxTerms( real64 const dt, { singlePhaseReactiveFVMKernels:: FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, + m_hasDiffusion, dofManager.rankOffset(), dofKey, getName(), @@ -390,6 +437,15 @@ void SinglePhaseReactiveTransport::initializeFluidState( MeshLevel & mesh, strin SinglePhaseBase::updateMass( subRegion ); updateSpeciesAmount( subRegion ); + + // If the diffusion is supported, initialize the model + if( m_hasDiffusion ) + { + string const & diffusionName = subRegion.template getReference< string >( viewKeyStruct::diffusionNamesString() ); + DiffusionBase const & diffusionMaterial = getConstitutiveModel< DiffusionBase >( subRegion, diffusionName ); + arrayView1d< real64 const > const temperature = subRegion.template getField< fields::flow::temperature >(); + diffusionMaterial.initializeTemperatureState( temperature ); + } } ); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index b9f137cebac..e560c2ddc05 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -124,6 +124,11 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase virtual void resetStateToBeginningOfStep( DomainPartition & domain ) override; + virtual void + implicitStepComplete( real64 const & time, + real64 const & dt, + DomainPartition & domain ) override final; + virtual void saveConvergedState( ElementSubRegionBase & subRegion ) const override final; virtual void @@ -224,6 +229,11 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) override; + struct viewKeyStruct : SinglePhaseBase::viewKeyStruct + { + static constexpr char const * diffusionNamesString() { return "diffusionNames"; } + }; + protected: virtual FluidPropViews getFluidProperties( constitutive::ConstitutiveBase const & fluid ) const override; @@ -233,6 +243,9 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase /// name of the reactive fluid constitutive model string m_reactiveFluidModelName; + + /// flag to determine whether or not to apply diffusion + integer m_hasDiffusion; }; template< typename OBJECT_TYPE > diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp index 6e2a8882761..25ce6abfd7c 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp @@ -20,6 +20,10 @@ #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_FLUXCOMPUTEKERNEL_HPP #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_FLUXCOMPUTEKERNEL_HPP +#include "constitutive/diffusion/DiffusionFields.hpp" +#include "constitutive/diffusion/DiffusionBase.hpp" +#include "constitutive/solid/porosity/PorosityBase.hpp" +#include "constitutive/solid/porosity/PorosityFields.hpp" #include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" #include "constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/FluxComputeKernel.hpp" @@ -93,6 +97,15 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S fields::reactivefluid::primarySpeciesAggregateConcentration, fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimaryConc >; + using DiffusionAccessors = + StencilMaterialAccessors< constitutive::DiffusionBase, + fields::diffusion::diffusivity, + fields::diffusion::dDiffusivity_dTemperature >; + + using PorosityAccessors = + StencilMaterialAccessors< constitutive::PorosityBase, + fields::porosity::referencePorosity >; + /** * @brief Constructor for the kernel interface * @param[in] rankOffset the offset of my MPI rank @@ -113,6 +126,9 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S SinglePhaseFluidAccessors const & singlePhaseFluidAccessors, ReactiveSinglePhaseFluidAccessors const & reactiveSinglePhaseFluidAccessors, PermeabilityAccessors const & permeabilityAccessors, + DiffusionAccessors const & diffusionAccessors, + PorosityAccessors const & porosityAccessors, + integer const & hasDiffusion, real64 const & dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) @@ -128,7 +144,11 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S m_logPrimarySpeciesConc( reactiveSinglePhaseFlowAccessors.get( fields::flow::logPrimarySpeciesConcentration {} ) ), m_dMob_dLogPrimaryConc( reactiveSinglePhaseFlowAccessors.get( fields::flow::dMobility_dLogPrimaryConc {} ) ), m_primarySpeciesAggregateConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::primarySpeciesAggregateConcentration {} ) ), - m_dPrimarySpeciesAggregateConc_dLogPrimaryConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimaryConc {} ) ) + m_dPrimarySpeciesAggregateConc_dLogPrimaryConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimaryConc {} ) ), + m_diffusivity( diffusionAccessors.get( fields::diffusion::diffusivity {} ) ), + m_dDiffusivity_dTemp( diffusionAccessors.get( fields::diffusion::dDiffusivity_dTemperature {} ) ), + m_referencePorosity( porosityAccessors.get( fields::porosity::referencePorosity {} ) ), + m_hasDiffusion( hasDiffusion ) {} /** @@ -156,6 +176,12 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S using Base::StackVariables::dofColIndices; using Base::StackVariables::localFlux; using Base::StackVariables::localFluxJacobian; + + /// Diffusion transmissibility + real64 diffusionTransmissibility[maxNumConns][numFluxSupportPoints]{}; + /// Derivatives of diffusion transmissibility with respect to temperature + real64 dDiffusionTrans_dT[maxNumConns][numFluxSupportPoints]{}; + }; /** @@ -165,9 +191,11 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S * @param[inout] stack the stack variables * @param[in] NoOpFunc the function used to customize the computation of the flux */ + template< typename FUNC = NoOpFunc > GEOS_HOST_DEVICE void computeFlux( localIndex const iconn, - StackVariables & stack ) const + StackVariables & stack, + FUNC && kernelOp = NoOpFunc{} ) const { using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; // *********************************************** @@ -208,20 +236,20 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S // compute species fluxes and derivatives using upstream cell composition for( integer is = 0; is < numSpecies; ++is ) { - real64 const totalConc_i = m_primarySpeciesAggregateConc[er_up][esr_up][ei_up][is]; - speciesFlux[is] = totalConc_i / fluidDens_up * fluxVal; + real64 const aggregateConc_i = m_primarySpeciesAggregateConc[er_up][esr_up][ei_up][is]; + speciesFlux[is] = aggregateConc_i / fluidDens_up * fluxVal; for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) { - dSpeciesFlux_dP[ke][is] += totalConc_i / fluidDens_up * dFlux_dP[ke]; + dSpeciesFlux_dP[ke][is] += aggregateConc_i / fluidDens_up * dFlux_dP[ke]; } - dSpeciesFlux_dP[k_up][is] += -totalConc_i * fluxVal * dDens_dPres / (fluidDens_up * fluidDens_up); + dSpeciesFlux_dP[k_up][is] += -aggregateConc_i * fluxVal * dDens_dPres / (fluidDens_up * fluidDens_up); for( integer js = 0; js < numSpecies; ++js ) { - real64 const dTotalConc_i_dLogConc_j = m_dPrimarySpeciesAggregateConc_dLogPrimaryConc[er_up][esr_up][ei_up][is][js]; - dSpeciesFlux_dLogConc[k_up][is][js] += dTotalConc_i_dLogConc_j / fluidDens_up * fluxVal; + real64 const dAggregateConc_i_dLogConc_j = m_dPrimarySpeciesAggregateConc_dLogPrimaryConc[er_up][esr_up][ei_up][is][js]; + dSpeciesFlux_dLogConc[k_up][is][js] += dAggregateConc_i_dLogConc_j / fluidDens_up * fluxVal; } } @@ -248,7 +276,118 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S } } } + + // Customize the kernel with this lambda + kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP ); } ); + + // ***************************************************** + // Computation of the diffusion term in the species flux + + if( m_hasDiffusion ) + { + // Step 1: compute the diffusion transmissibilities at this face + m_stencilWrapper.computeWeights( iconn, + m_diffusivity, + m_dDiffusivity_dTemp, + stack.diffusionTransmissibility, + stack.dDiffusionTrans_dT ); + + localIndex k[numFluxSupportPoints]{}; + localIndex connectionIndex = 0; + + for( k[0] = 0; k[0] < stack.numFluxElems; ++k[0] ) + { + for( k[1] = k[0] + 1; k[1] < stack.numFluxElems; ++k[1] ) + { + localIndex const seri[numFluxSupportPoints] = {m_seri( iconn, k[0] ), m_seri( iconn, k[1] )}; + localIndex const sesri[numFluxSupportPoints] = {m_sesri( iconn, k[0] ), m_sesri( iconn, k[1] )}; + localIndex const sei[numFluxSupportPoints] = {m_sei( iconn, k[0] ), m_sei( iconn, k[1] )}; + + // clear working arrays + real64 diffusionFlux[numSpecies]{}; + // real64 dDiffusionFlux_dP[numFluxSupportPoints][numSpecies]{}; // Turn on if diffusionFlux is pressure-dependent + real64 dDiffusionFlux_dLogConc[numFluxSupportPoints][numSpecies][numSpecies]{}; + + real64 const diffusionTrans[numFluxSupportPoints] = { stack.diffusionTransmissibility[connectionIndex][0], + stack.diffusionTransmissibility[connectionIndex][1] }; + + //***** calculation of flux ***** + // loop over primary species + for( integer is = 0; is < numSpecies; ++is ) + { + real64 speciesGrad_i = 0.0; + // real64 dSpeciesGrad_i_dP[numFluxSupportPoints]{}; // Turn on if speciesGrad is pressure-dependent + real64 dSpeciesGrad_i_dLogConc[numFluxSupportPoints][numSpecies]{}; + + // Step 2: compute species gradient + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + localIndex const er = seri[ke]; + localIndex const esr = sesri[ke]; + localIndex const ei = sei[ke]; + + real64 const aggregateConc_i = m_primarySpeciesAggregateConc[er][esr][ei][is]; + + speciesGrad_i += diffusionTrans[ke] * aggregateConc_i; + + for( integer js = 0; js < numSpecies; ++js ) + { + real64 const dAggregateConc_i_dLogConc_j = m_dPrimarySpeciesAggregateConc_dLogPrimaryConc[er][esr][ei][is][js]; + + dSpeciesGrad_i_dLogConc[ke][js] += diffusionTrans[ke] * dAggregateConc_i_dLogConc_j; + } + } + + // choose upstream cell for species upwinding + localIndex const k_up = (speciesGrad_i >= 0) ? 0 : 1; + + localIndex const er_up = seri[k_up]; + localIndex const esr_up = sesri[k_up]; + localIndex const ei_up = sei[k_up]; + + // computation of the upwinded species flux + diffusionFlux[is] += m_referencePorosity[er_up][esr_up][ei_up] * speciesGrad_i; + + // add contributions of the derivatives of component fractions wrt pressure/component fractions + for( integer ke = 0; ke < numFluxSupportPoints; ke++ ) + { + for( integer js = 0; js < numSpecies; ++js ) + { + dDiffusionFlux_dLogConc[ke][is][js] += m_referencePorosity[er_up][esr_up][ei_up] * dSpeciesGrad_i_dLogConc[ke][js]; + } + } + } // loop over primary species + + // Add the local diffusion flux contribution to the residual and Jacobian + // loop over primary species + for( integer is = 0; is < numSpecies; ++is ) + { + integer const eqIndex0 = k[0] * numEqn + is + 1; + integer const eqIndex1 = k[1] * numEqn + is + 1; + + stack.localFlux[eqIndex0] += m_dt * diffusionFlux[is]; + stack.localFlux[eqIndex1] -= m_dt * diffusionFlux[is]; + + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + localIndex const localDofIndexPres = k[ke] * numDof; + // stack.localFluxJacobian[eqIndex0][localDofIndexPres] += m_dt * dDiffusionFlux_dP[ke][is]; + // stack.localFluxJacobian[eqIndex1][localDofIndexPres] -= m_dt * dDiffusionFlux_dP[ke][is]; + + for( integer js = 0; js < numSpecies; ++js ) + { + localIndex const localDofIndexComp = localDofIndexPres + js + 1; + stack.localFluxJacobian[eqIndex0][localDofIndexComp] += m_dt * dDiffusionFlux_dLogConc[ke][is][js]; + stack.localFluxJacobian[eqIndex1][localDofIndexComp] -= m_dt * dDiffusionFlux_dLogConc[ke][is][js]; + } + } + } + + connectionIndex++; + } + } + } } /** @@ -287,11 +426,21 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S /// Views on derivatives of fluid mobilities ElementViewConst< arrayView2d< real64 const, compflow::USD_FLUID_DC > > const m_dMob_dLogPrimaryConc; - /// Views on primary species total concentration + /// Views on primary species aggregate concentration ElementViewConst< arrayView2d< real64 const, compflow::USD_COMP > > const m_primarySpeciesAggregateConc; - /// Views on primary species total concentration + /// Views on primary species aggregate concentration ElementViewConst< arrayView3d< real64 const, compflow::USD_COMP_DC > > const m_dPrimarySpeciesAggregateConc_dLogPrimaryConc; + + /// Views on diffusivity + ElementViewConst< arrayView3d< real64 const > > const m_diffusivity; + ElementViewConst< arrayView3d< real64 const > > const m_dDiffusivity_dTemp; + + /// View on the reference porosity + ElementViewConst< arrayView1d< real64 const > > const m_referencePorosity; + + /// Flag of adding the diffusion term + integer const m_hasDiffusion; }; /** @@ -306,6 +455,7 @@ class FluxComputeKernelFactory * @tparam POLICY the policy used in the RAJA kernel * @tparam STENCILWRAPPER the type of the stencil wrapper * @param[in] numSpecies the number of primary species + * @param[in] hasDiffusion the flag of adding diffusion term * @param[in] rankOffset the offset of my MPI rank * @param[in] dofKey string to get the element degrees of freedom numbers * @param[in] solverName name of the solver (to name accessors) @@ -318,6 +468,7 @@ class FluxComputeKernelFactory template< typename POLICY, typename STENCILWRAPPER > static void createAndLaunch( integer const numSpecies, + integer const hasDiffusion, globalIndex const rankOffset, string const & dofKey, string const & solverName, @@ -342,10 +493,12 @@ class FluxComputeKernelFactory typename KernelType::SinglePhaseFluidAccessors fluidAccessors( elemManager, solverName ); typename KernelType::ReactiveSinglePhaseFluidAccessors reactiveFluidAccessors( elemManager, solverName ); typename KernelType::PermeabilityAccessors permAccessors( elemManager, solverName ); + typename KernelType::DiffusionAccessors diffusionAccessors( elemManager, solverName ); + typename KernelType::PorosityAccessors porosityAccessors( elemManager, solverName ); KernelType kernel( rankOffset, stencilWrapper, dofNumberAccessor, - flowAccessors, reactiveFlowAccessors, fluidAccessors, - reactiveFluidAccessors, permAccessors, + flowAccessors, reactiveFlowAccessors, fluidAccessors, reactiveFluidAccessors, + permAccessors, diffusionAccessors, porosityAccessors, hasDiffusion, dt, localMatrix, localRhs ); KernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); } ); From 253cf7118cf932426379eac494d9df4783c65bfc Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Tue, 18 Mar 2025 16:27:55 -0700 Subject: [PATCH 04/12] resolve merge conflict for logLevel issue --- .../fluidFlow/SinglePhaseReactiveTransport.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index a0154546539..92abe27bf31 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -27,6 +27,7 @@ #include "constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp" #include "finiteVolume/FluxApproximationBase.hpp" #include "mesh/DomainPartition.hpp" +#include "physicsSolvers/LogLevelsInfo.hpp" /** * @namespace the geos namespace that encapsulates the majority of the code @@ -44,6 +45,8 @@ SinglePhaseReactiveTransport::SinglePhaseReactiveTransport( const string & name, m_hasDiffusion( 0 ) { // To add modeling parameters we want to add here + + addLogLevel< logInfo::Convergence >(); } // TODO: we need to update the class of ReactiveSingleFluid to be consistent with the chemistry module!!! @@ -907,8 +910,8 @@ real64 SinglePhaseReactiveTransport::calculateResidualNorm( real64 const & GEOS_ } residualNorm = sqrt( globalResidualNorm[0] * globalResidualNorm[0] + globalResidualNorm[1] * globalResidualNorm[1] + globalResidualNorm[2] * globalResidualNorm[2] ); - GEOS_LOG_LEVEL_INFO_RANK_0_NLR( logInfo::Convergence, GEOS_FMT( " ( RtotalMass RspeciesAmount ) = ( {:4.2e} {:4.2e} ) ( Renergy ) = ( {:4.2e} )", - globalResidualNorm[0], globalResidualNorm[2], globalResidualNorm[1] )); + GEOS_LOG_LEVEL_RANK_0_NLR( logInfo::Convergence, GEOS_FMT( " ( RtotalMass RspeciesAmount ) = ( {:4.2e} {:4.2e} ) ( Renergy ) = ( {:4.2e} )", + globalResidualNorm[0], globalResidualNorm[2], globalResidualNorm[1] )); } else { @@ -924,8 +927,8 @@ real64 SinglePhaseReactiveTransport::calculateResidualNorm( real64 const & GEOS_ } residualNorm = sqrt( globalResidualNorm[0] * globalResidualNorm[0] + globalResidualNorm[1] * globalResidualNorm[1] ); - GEOS_LOG_LEVEL_INFO_RANK_0_NLR( logInfo::Convergence, GEOS_FMT( " ( RtotalMass RspeciesAmount ) = ( {:4.2e} {:4.2e} )", - globalResidualNorm[0], globalResidualNorm[1] ) ); + GEOS_LOG_LEVEL_RANK_0_NLR( logInfo::Convergence, GEOS_FMT( " ( RtotalMass RspeciesAmount ) = ( {:4.2e} {:4.2e} )", + globalResidualNorm[0], globalResidualNorm[1] ) ); } return residualNorm; } From 39b6098a82c35a04d90e33443b340d244da6d4e3 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Fri, 28 Mar 2025 09:40:15 -0700 Subject: [PATCH 05/12] enabled thermal and fixed a few bugs --- .../constitutive/CMakeLists.txt | 2 + .../reactive/ReactiveFluidSelector.hpp | 7 +- .../fluid/singlefluid/SingleFluidBase.hpp | 4 +- .../fluid/singlefluid/SingleFluidSelector.hpp | 7 +- .../ReactiveCompressibleSinglePhaseFluid.hpp | 6 +- .../reactive/ReactiveSingleFluid.hpp | 2 +- ...alReactiveCompressibleSinglePhaseFluid.cpp | 128 ++++ ...alReactiveCompressibleSinglePhaseFluid.hpp | 333 ++++++++++ .../physicsSolvers/fluidFlow/CMakeLists.txt | 2 + .../fluidFlow/SinglePhaseBase.cpp | 4 +- .../fluidFlow/SinglePhaseBase.hpp | 2 +- .../SinglePhaseReactiveTransport.cpp | 35 +- .../SinglePhaseReactiveTransport.hpp | 16 +- .../reactive/AccumulationKernels.hpp | 20 +- .../reactive/FluxComputeKernel.hpp | 120 +++- .../reactive/ThermalAccumulationKernels.hpp | 259 ++++++++ .../reactive/ThermalFluxComputeKernel.hpp | 628 ++++++++++++++++++ 17 files changed, 1485 insertions(+), 90 deletions(-) create mode 100644 src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.cpp create mode 100644 src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index aa67a863e4a..a7ca07f60a5 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -130,6 +130,7 @@ set( constitutive_headers fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp fluid/singlefluid/reactive/ReactiveSingleFluid.hpp + fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp permeability/CarmanKozenyPermeability.hpp permeability/ConstantPermeability.hpp permeability/ExponentialDecayPermeability.hpp @@ -269,6 +270,7 @@ set( constitutive_sources fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.cpp fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.cpp fluid/singlefluid/reactive/ReactiveSingleFluid.cpp + fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.cpp permeability/CarmanKozenyPermeability.cpp permeability/ConstantPermeability.cpp permeability/ExponentialDecayPermeability.cpp diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp index d6fd9bf8ca1..71b42c912f0 100644 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp +++ b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp @@ -22,6 +22,7 @@ #include "constitutive/ConstitutivePassThruHandler.hpp" #include "constitutive/fluid/multifluid/reactive/ReactiveBrineFluid.hpp" #include "constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp" +#include "constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp" #include "common/GeosxConfig.hpp" @@ -51,14 +52,16 @@ template< typename LAMBDA > void constitutiveUpdatePassThru( ReactiveSingleFluid const & fluid, LAMBDA && lambda ) { - ConstitutivePassThruHandler< ReactiveCompressibleSinglePhase >::execute( fluid, std::forward< LAMBDA >( lambda ) ); + ConstitutivePassThruHandler< ReactiveCompressibleSinglePhase, + ThermalReactiveCompressibleSinglePhase >::execute( fluid, std::forward< LAMBDA >( lambda ) ); } template< typename LAMBDA > void constitutiveUpdatePassThru( ReactiveSingleFluid & fluid, LAMBDA && lambda ) { - ConstitutivePassThruHandler< ReactiveCompressibleSinglePhase >::execute( fluid, std::forward< LAMBDA >( lambda ) ); + ConstitutivePassThruHandler< ReactiveCompressibleSinglePhase, + ThermalReactiveCompressibleSinglePhase >::execute( fluid, std::forward< LAMBDA >( lambda ) ); } } // namespace constitutive diff --git a/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidBase.hpp b/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidBase.hpp index 48fead16717..af8c4e3fddf 100644 --- a/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidBase.hpp +++ b/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidBase.hpp @@ -212,14 +212,14 @@ class SingleFluidBaseUpdate * @param[in] q gauss point index * @param[in] pressure the target pressure value * @param[in] temperature the target temperature value - * @param[in] composition the target composition value + * @param[in] logPrimaryConc the target logPrimaryConc value */ GEOS_HOST_DEVICE virtual void update( localIndex const k, localIndex const q, real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition ) const = 0; + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimaryConc ) const = 0; }; //END_SPHINX_INCLUDE_02 diff --git a/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidSelector.hpp b/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidSelector.hpp index 7f0db718d52..ba378a397e1 100644 --- a/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidSelector.hpp +++ b/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidSelector.hpp @@ -23,6 +23,7 @@ #include "constitutive/fluid/singlefluid/CompressibleSinglePhaseFluid.hpp" #include "constitutive/fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp" #include "constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp" +#include "constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp" namespace geos { @@ -34,7 +35,8 @@ template< typename LAMBDA > void constitutiveUpdatePassThru( SingleFluidBase const & fluid, LAMBDA && lambda ) { - ConstitutivePassThruHandler< ReactiveCompressibleSinglePhase, + ConstitutivePassThruHandler< ThermalReactiveCompressibleSinglePhase, + ReactiveCompressibleSinglePhase, ThermalCompressibleSinglePhaseFluid, CompressibleSinglePhaseFluid >::execute( fluid, std::forward< LAMBDA >( lambda ) ); } @@ -43,7 +45,8 @@ template< typename LAMBDA > void constitutiveUpdatePassThru( SingleFluidBase & fluid, LAMBDA && lambda ) { - ConstitutivePassThruHandler< ReactiveCompressibleSinglePhase, + ConstitutivePassThruHandler< ThermalReactiveCompressibleSinglePhase, + ReactiveCompressibleSinglePhase, ThermalCompressibleSinglePhaseFluid, CompressibleSinglePhaseFluid >::execute( fluid, std::forward< LAMBDA >( lambda ) ); } diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp index 2364e091391..82896312e50 100644 --- a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp @@ -146,7 +146,7 @@ class ReactiveCompressibleSinglePhaseUpdate : public ReactiveSingleFluidUpdate localIndex const q, real64 const pressure, real64 const GEOS_UNUSED_PARAM( temperature ), - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & GEOS_UNUSED_PARAM( composition ) ) const override + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & GEOS_UNUSED_PARAM( logPrimaryConc ) ) const override { compute( pressure, m_density[k][q], @@ -161,11 +161,11 @@ class ReactiveCompressibleSinglePhaseUpdate : public ReactiveSingleFluidUpdate localIndex const GEOS_UNUSED_PARAM( q ), real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition ) const override + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primaryConc ) const override { for( int i=0; i < m_numPrimarySpecies; i++ ) { - m_primarySpeciesAggregateConcentration[k][i] = composition[i]; + m_primarySpeciesAggregateConcentration[k][i] = primaryConc[i]; } computeChemistry( pressure, diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp index dfbe85c1712..48a5457faba 100644 --- a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp +++ b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp @@ -51,7 +51,7 @@ class ReactiveSingleFluidUpdate : public SingleFluidBaseUpdate localIndex const q, real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition ) const = 0; + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primaryConc ) const = 0; GEOS_HOST_DEVICE virtual void updateChemistryLogConc( localIndex const k, diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.cpp new file mode 100644 index 00000000000..3f7a746cf72 --- /dev/null +++ b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.cpp @@ -0,0 +1,128 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ThermalReactiveCompressibleSinglePhaseFluid.cpp + */ + +#include "ThermalReactiveCompressibleSinglePhaseFluid.hpp" + +#include "constitutive/fluid/singlefluid/SingleFluidFields.hpp" + +namespace geos +{ + +using namespace dataRepository; + +namespace constitutive +{ + +ThermalReactiveCompressibleSinglePhase::ThermalReactiveCompressibleSinglePhase( string const & name, Group * const parent ): + ReactiveCompressibleSinglePhase( name, parent ), + m_internalEnergyModelType( ExponentApproximationType::Linear ) +{ + m_densityModelType = ExponentApproximationType::Full; + registerWrapper( viewKeyStruct::thermalExpansionCoeffString(), &m_thermalExpansionCoeff ). + setApplyDefaultValue( 0.0 ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Fluid thermal expansion coefficient. Unit: 1/K" ); + + registerWrapper( viewKeyStruct::specificHeatCapacityString(), &m_specificHeatCapacity ). + setApplyDefaultValue( 0.0 ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Fluid heat capacity. Unit: J/kg/K" ); + + registerWrapper( viewKeyStruct::referenceTemperatureString(), &m_referenceTemperature ). + setApplyDefaultValue( 0.0 ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Reference temperature" ); + + registerWrapper( viewKeyStruct::referenceInternalEnergyString(), &m_referenceInternalEnergy ). + setApplyDefaultValue( 0.001 ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Reference fluid internal energy" ); + + registerWrapper( viewKeyStruct::internalEnergyModelTypeString(), &m_internalEnergyModelType ). + setApplyDefaultValue( m_internalEnergyModelType ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Type of internal energy model. Valid options:\n* " + EnumStrings< ExponentApproximationType >::concat( "\n* " ) ); + +} + +ThermalReactiveCompressibleSinglePhase::~ThermalReactiveCompressibleSinglePhase() = default; + +void ThermalReactiveCompressibleSinglePhase::allocateConstitutiveData( dataRepository::Group & parent, + localIndex const numConstitutivePointsPerParentIndex ) +{ + ReactiveCompressibleSinglePhase::allocateConstitutiveData( parent, numConstitutivePointsPerParentIndex ); + + m_internalEnergy.value.setValues< serialPolicy >( m_referenceInternalEnergy ); +} + +void ThermalReactiveCompressibleSinglePhase::postInputInitialization() +{ + ReactiveCompressibleSinglePhase::postInputInitialization(); + + auto const checkNonnegative = [&]( real64 const value, auto const & attribute ) + { + GEOS_THROW_IF_LT_MSG( value, 0.0, + GEOS_FMT( "{}: invalid value of attribute '{}'", getFullName(), attribute ), + InputError ); + }; + + checkNonnegative( m_thermalExpansionCoeff, viewKeyStruct::thermalExpansionCoeffString() ); + checkNonnegative( m_specificHeatCapacity, viewKeyStruct::specificHeatCapacityString() ); + checkNonnegative( m_referenceInternalEnergy, viewKeyStruct::referenceInternalEnergyString() ); + + // Due to the way update wrapper is currently implemented, we can only support one model type + auto const checkModelType = [&]( ExponentApproximationType const value, auto const & attribute ) + { + GEOS_THROW_IF( value != ExponentApproximationType::Linear && value != ExponentApproximationType::Full, + GEOS_FMT( "{}: invalid model type in attribute '{}' (only linear or fully exponential currently supported)", getFullName(), attribute ), + InputError ); + }; + checkModelType( m_internalEnergyModelType, viewKeyStruct::internalEnergyModelTypeString() ); +} + +ThermalReactiveCompressibleSinglePhase::KernelWrapper +ThermalReactiveCompressibleSinglePhase::createKernelWrapper() +{ + return KernelWrapper( KernelWrapper::DensRelationType( m_referencePressure, m_referenceTemperature, m_referenceDensity, m_compressibility, -m_thermalExpansionCoeff ), + KernelWrapper::ViscRelationType( m_referencePressure, m_referenceViscosity, m_viscosibility ), + KernelWrapper::IntEnergyRelationType( m_referenceTemperature, m_referenceInternalEnergy, m_specificHeatCapacity/m_referenceInternalEnergy ), + m_density.value, + m_density.derivs, + m_viscosity.value, + m_viscosity.derivs, + m_numPrimarySpecies, + // *m_equilibriumReactions, + // *m_kineticReactions, + m_primarySpeciesConcentration.toView(), + m_secondarySpeciesConcentration.toView(), + m_primarySpeciesAggregateConcentration.toView(), + m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc.toView(), + m_kineticReactionRates.toView(), + m_internalEnergy.value, + m_internalEnergy.derivs, + m_enthalpy.value, + m_enthalpy.derivs, + m_referenceInternalEnergy ); +} + +REGISTER_CATALOG_ENTRY( ConstitutiveBase, ThermalReactiveCompressibleSinglePhase, string const &, Group * const ) + +} /* namespace constitutive */ + +} /* namespace geos */ diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp new file mode 100644 index 00000000000..8e0cdbdcfb1 --- /dev/null +++ b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp @@ -0,0 +1,333 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ThermalReactiveCompressibleSinglePhaseFluid.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_THERMALREACTIVECOMPRESSIBLESINGLEPHASEFLUID_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_THERMALREACTIVECOMPRESSIBLESINGLEPHASEFLUID_HPP_ + +#include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" +#include "constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp" + +#include "constitutive/ExponentialRelation.hpp" + +namespace geos +{ + +namespace constitutive +{ + +/** + * @brief Update class for the model suitable for lambda capture. + * @tparam DENS_EAT type of density exponent approximation for the pressure part + * @tparam VISC_EAT type of viscosity exponent approximation + * @tparam INTENERGY_EAT type of internal energy exponent approximation + */ +template< ExponentApproximationType DENS_EAT, ExponentApproximationType VISC_EAT, ExponentApproximationType INTENERGY_EAT > +class ThermalReactiveCompressibleSinglePhaseUpdate : public ReactiveSingleFluidUpdate +{ +public: + + using DensRelationType = ExponentialRelation< real64, DENS_EAT, 3 >; + using ViscRelationType = ExponentialRelation< real64, VISC_EAT >; + using IntEnergyRelationType = ExponentialRelation< real64, INTENERGY_EAT >; + using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; + + ThermalReactiveCompressibleSinglePhaseUpdate( DensRelationType const & densRelation, + ViscRelationType const & viscRelation, + IntEnergyRelationType const & intEnergyRelation, + arrayView2d< real64, constitutive::singlefluid::USD_FLUID > const & density, + arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > const & dDensity, + arrayView2d< real64, constitutive::singlefluid::USD_FLUID > const & viscosity, + arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > const & dViscosity, + integer const numPrimarySpecies, + // chemicalReactions::EquilibriumReactions const & equilibriumReactions, + // chemicalReactions::KineticReactions const & kineticReactions, + arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesConcentration, + arrayView2d< real64, compflow::USD_COMP > const & secondarySpeciesConcentration, + arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesAggregateConcentration, + arrayView3d< real64, compflow::USD_COMP_DC > const & dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, + arrayView2d< real64, compflow::USD_COMP > const & kineticReactionRates, + arrayView2d< real64, constitutive::singlefluid::USD_FLUID > const & internalEnergy, + arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > const & dInternalEnergy, + arrayView2d< real64, constitutive::singlefluid::USD_FLUID > const & enthalpy, + arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > const & dEnthalpy, + real64 const & refIntEnergy ) + : ReactiveSingleFluidUpdate( density, dDensity, viscosity, dViscosity, numPrimarySpecies, + // equilibriumReactions, kineticReactions, + primarySpeciesConcentration, secondarySpeciesConcentration, primarySpeciesAggregateConcentration, + dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, kineticReactionRates ), + m_internalEnergy( internalEnergy ), + m_dInternalEnergy( dInternalEnergy ), + m_enthalpy( enthalpy ), + m_dEnthalpy( dEnthalpy ), + m_densRelation( densRelation ), + m_viscRelation( viscRelation ), + m_intEnergyRelation( intEnergyRelation ), + m_refIntEnergy( refIntEnergy ) + {} + + /// Default copy constructor + ThermalReactiveCompressibleSinglePhaseUpdate( ThermalReactiveCompressibleSinglePhaseUpdate const & ) = default; + + /// Default move constructor + ThermalReactiveCompressibleSinglePhaseUpdate( ThermalReactiveCompressibleSinglePhaseUpdate && ) = default; + + /// Deleted copy assignment operator + ThermalReactiveCompressibleSinglePhaseUpdate & operator=( ThermalReactiveCompressibleSinglePhaseUpdate const & ) = delete; + + /// Deleted move assignment operator + ThermalReactiveCompressibleSinglePhaseUpdate & operator=( ThermalReactiveCompressibleSinglePhaseUpdate && ) = delete; + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void compute( real64 const pressure, + real64 & density, + real64 & dDensity_dPressure, + real64 & viscosity, + real64 & dViscosity_dPressure ) const override + { + m_densRelation.compute( pressure, density, dDensity_dPressure ); + m_viscRelation.compute( pressure, viscosity, dViscosity_dPressure ); + } + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void compute( real64 const pressure, + real64 const temperature, + real64 & density, + real64 & dDensity_dPressure, + real64 & dDensity_dTemperature, + real64 & viscosity, + real64 & dViscosity_dPressure, + real64 & dViscosity_dTemperature, + real64 & internalEnergy, + real64 & dInternalEnergy_dPressure, + real64 & dInternalEnergy_dTemperature, + real64 & enthalpy, + real64 & dEnthalpy_dPressure, + real64 & dEnthalpy_dTemperature ) const override + { + m_viscRelation.compute( pressure, viscosity, dViscosity_dPressure ); + dViscosity_dTemperature = 0.0; + + m_densRelation.compute( pressure, temperature, density, dDensity_dPressure, dDensity_dTemperature ); + + /// Compute the internal energy (only sensitive to temperature) + m_intEnergyRelation.compute( temperature, internalEnergy, dInternalEnergy_dTemperature ); + dInternalEnergy_dPressure = 0.0; + + enthalpy = internalEnergy - m_refIntEnergy; + dEnthalpy_dPressure = 0.0; + dEnthalpy_dTemperature = dInternalEnergy_dTemperature; + + } + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void update( localIndex const k, + localIndex const q, + real64 const pressure ) const override + { + compute( pressure, + m_density[k][q], + m_dDensity[k][q][DerivOffset::dP], + m_viscosity[k][q], + m_dViscosity[k][q][DerivOffset::dP] ); + } + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void update( localIndex const k, + localIndex const q, + real64 const pressure, + real64 const temperature ) const override + { + compute( pressure, + temperature, + m_density[k][q], + m_dDensity[k][q][DerivOffset::dP], + m_dDensity[k][q][DerivOffset::dT], + m_viscosity[k][q], + m_dViscosity[k][q][DerivOffset::dP], + m_dViscosity[k][q][DerivOffset::dT], + m_internalEnergy[k][q], + m_dInternalEnergy[k][q][DerivOffset::dP], + m_dInternalEnergy[k][q][DerivOffset::dT], + m_enthalpy[k][q], + m_dEnthalpy[k][q][DerivOffset::dP], + m_dEnthalpy[k][q][DerivOffset::dT] ); + } + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void update( localIndex const k, + localIndex const q, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & GEOS_UNUSED_PARAM( composition ) ) const override + { + compute( pressure, + temperature, + m_density[k][q], + m_dDensity[k][q][DerivOffset::dP], + m_dDensity[k][q][DerivOffset::dT], + m_viscosity[k][q], + m_dViscosity[k][q][DerivOffset::dP], + m_dViscosity[k][q][DerivOffset::dT], + m_internalEnergy[k][q], + m_dInternalEnergy[k][q][DerivOffset::dP], + m_dInternalEnergy[k][q][DerivOffset::dT], + m_enthalpy[k][q], + m_dEnthalpy[k][q][DerivOffset::dP], + m_dEnthalpy[k][q][DerivOffset::dT] ); + } + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void updateChemistry( localIndex const k, + localIndex const GEOS_UNUSED_PARAM( q ), + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primaryConc ) const override + { + for( int i=0; i < m_numPrimarySpecies; i++ ) + { + m_primarySpeciesAggregateConcentration[k][i] = primaryConc[i]; + } + + computeChemistry( pressure, + temperature, + m_primarySpeciesAggregateConcentration[k], + m_primarySpeciesConcentration[k], + m_secondarySpeciesConcentration[k], + m_kineticReactionRates[k] ); + } + + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + virtual void updateChemistryLogConc( localIndex const k, + localIndex const GEOS_UNUSED_PARAM( q ), + real64 const GEOS_UNUSED_PARAM( pressure ), + real64 const GEOS_UNUSED_PARAM( temperature ), + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimaryConc ) const override + { + for( int i=0; i < m_numPrimarySpecies; i++ ) + { + m_primarySpeciesConcentration[k][i] = std::exp( logPrimaryConc[i] ); + + m_primarySpeciesAggregateConcentration[k][i] = m_primarySpeciesConcentration[k][i]; + + m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc[k][i][i] = m_primarySpeciesConcentration[k][i]; + } + + // computeChemistry( pressure, + // temperature, + // m_primarySpeciesAggregateConcentration[k], + // m_primarySpeciesConcentration[k], + // m_secondarySpeciesConcentration[k], + // m_kineticReactionRates[k] ); + } + +private: + + /// Fluid internal energy and derivatives + arrayView2d< real64, constitutive::singlefluid::USD_FLUID > m_internalEnergy; + arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > m_dInternalEnergy; + + /// Fluid enthalpy and derivatives + arrayView2d< real64, constitutive::singlefluid::USD_FLUID > m_enthalpy; + arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > m_dEnthalpy; + + /// Relationship between the fluid density and pressure & temperature + DensRelationType m_densRelation; + + /// Relationship between the fluid viscosity and pressure + ViscRelationType m_viscRelation; + + /// Relationship between the fluid internal energy and temperature + IntEnergyRelationType m_intEnergyRelation; + + /// Reference internal energy of the fluid + real64 const m_refIntEnergy; + +}; + +class ThermalReactiveCompressibleSinglePhase : public ReactiveCompressibleSinglePhase +{ +public: + + ThermalReactiveCompressibleSinglePhase( string const & name, Group * const parent ); + + virtual ~ThermalReactiveCompressibleSinglePhase() override; + + static string catalogName() { return "ThermalReactiveCompressibleSinglePhase"; } + + virtual string getCatalogName() const override { return catalogName(); } + + virtual void allocateConstitutiveData( dataRepository::Group & parent, + localIndex const numConstitutivePointsPerParentIndex ) override; + + using ReactiveCompressibleSinglePhase::m_densityModelType; + + /// Type of kernel wrapper for in-kernel update (TODO: support multiple EAT, not just linear) + using KernelWrapper = ThermalReactiveCompressibleSinglePhaseUpdate< ExponentApproximationType::Full, ExponentApproximationType::Linear, ExponentApproximationType::Linear >; + + /** + * @brief Create an update kernel wrapper. + * @return the wrapper + */ + KernelWrapper createKernelWrapper(); + + struct viewKeyStruct : public ReactiveCompressibleSinglePhase::viewKeyStruct + { + static constexpr char const * thermalExpansionCoeffString() { return "thermalExpansionCoeff"; } + static constexpr char const * specificHeatCapacityString() { return "specificHeatCapacity"; } + static constexpr char const * referenceTemperatureString() { return "referenceTemperature"; } + static constexpr char const * referenceInternalEnergyString() { return "referenceInternalEnergy"; } + static constexpr char const * internalEnergyModelTypeString() { return "internalEnergyModelType"; } + }; + + virtual bool isThermal() const override { return true; } + +protected: + + virtual void postInputInitialization() override; + +private: + + /// scalar fluid thermal expansion coefficient + real64 m_thermalExpansionCoeff; + + /// scalar fluid volumetric heat capacity coefficient + real64 m_specificHeatCapacity; + + /// reference temperature parameter + real64 m_referenceTemperature; + + /// reference internal energy parameter + real64 m_referenceInternalEnergy; + + /// type of internal energy model + ExponentApproximationType m_internalEnergyModelType; +}; + +} /* namespace constitutive */ + +} /* namespace geos */ + +#endif /* GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_THERMALREACTIVECOMPRESSIBLESINGLEPHASEFLUID_HPP_ */ diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt index e56f10cf2ef..f7f6af1aca4 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt +++ b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt @@ -68,6 +68,8 @@ set( fluidFlowSolvers_headers kernels/singlePhase/reactive/FluxComputeKernel.hpp kernels/singlePhase/reactive/KernelLaunchSelectors.hpp kernels/singlePhase/reactive/ResidualNormKernel.hpp + kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp + kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp kernels/compositional/AccumulationKernel.hpp kernels/compositional/AquiferBCKernel.hpp kernels/compositional/PPUPhaseFlux.hpp diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp index ab3b1bdf362..9999ed77e8e 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp @@ -195,11 +195,11 @@ void SinglePhaseBase::validateConstitutiveModels( DomainPartition & domain ) con constitutiveUpdatePassThru( fluid, [&] ( auto & castedFluid ) { string const fluidModelName = castedFluid.getCatalogName(); - GEOS_THROW_IF( m_isThermal && (fluidModelName != "ThermalCompressibleSinglePhaseFluid"), + GEOS_THROW_IF( m_isThermal && ((fluidModelName != "ThermalCompressibleSinglePhaseFluid") && (fluidModelName != "ThermalReactiveCompressibleSinglePhase")), GEOS_FMT( "SingleFluidBase {}: the thermal option is enabled in the solver, but the fluid model {} is not for thermal fluid", getDataContext(), fluid.getDataContext() ), InputError ); - GEOS_THROW_IF( !m_isThermal && (fluidModelName == "ThermalCompressibleSinglePhaseFluid"), + GEOS_THROW_IF( !m_isThermal && ((fluidModelName == "ThermalCompressibleSinglePhaseFluid") || (fluidModelName == "ThermalReactiveCompressibleSinglePhase")), GEOS_FMT( "SingleFluidBase {}: the fluid model is for thermal fluid {}, but the solver option is incompatible with the fluid model", getDataContext(), fluid.getDataContext() ), InputError ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.hpp index d0d16f26b76..a8f3f6644a3 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.hpp @@ -222,7 +222,7 @@ class SinglePhaseBase : public FlowSolverBase * @param localMatrix local system matrix * @param localRhs local system right-hand side vector */ - void + virtual void applyDirichletBC( real64 const time_n, real64 const dt, DomainPartition & domain, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 92abe27bf31..c09bebd7adb 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -94,7 +94,7 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) // n_c components + one pressure ( + one temperature if needed ) m_numDofPerCell = m_isThermal ? m_numPrimarySpecies + 2 : m_numPrimarySpecies + 1; - // 2. Register and resize all fields as necessary (to finish) + // 2. Register and resize all fields as necessary forDiscretizationOnMeshTargets( meshBodies, [&]( string const &, MeshLevel & mesh, string_array const & regionNames ) @@ -263,7 +263,7 @@ void SinglePhaseReactiveTransport::assembleAccumulationTermsInMassBalanceAndSpec if( m_isThermal ) { - singlePhaseReactiveBaseKernels:: + thermalSinglePhaseReactiveBaseKernels:: AccumulationKernelFactory:: createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, dt, @@ -313,9 +313,9 @@ void SinglePhaseReactiveTransport::assembleFluxTerms( real64 const dt, { typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper(); - if( m_isThermal ) // To implement the thermal case + if( m_isThermal ) { - singlePhaseReactiveFVMKernels:: + thermalSinglePhaseReactiveFVMKernels:: FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, m_hasDiffusion, dofManager.rankOffset(), @@ -483,25 +483,14 @@ void SinglePhaseReactiveTransport::applyBoundaryConditions( real64 const time_n, { GEOS_MARK_FUNCTION; - // if( m_keepVariablesConstantDuringInitStep ) - // { - // // this function is going to force the current flow state to be constant during the time step - // // this is used when the poromechanics solver is performing the stress initialization - // // TODO: in the future, a dedicated poromechanics kernel should eliminate the flow vars to construct a reduced system - // // which will remove the need for this brittle passing aroung of flag - // keepVariablesConstantDuringInitStep( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); - // } - // else - // { // apply pressure boundary conditions. - applyPresSpeciesDirichletBC( time_n, dt, domain, dofManager, localMatrix.toViewConstSizes(), localRhs.toView() ); + applyDirichletBC( time_n, dt, domain, dofManager, localMatrix.toViewConstSizes(), localRhs.toView() ); // // apply flux boundary conditions (To finish) // applySourceFluxBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); // // apply aquifer boundary conditions (To finish) // applyAquiferBC( time_n, dt, dofManager, domain, localMatrix.toViewConstSizes(), localRhs.toView() ); - // } } // // To finish @@ -668,12 +657,12 @@ char const bcLogMessage[] = "\nNote that if this number is equal to zero for all subRegions, the boundary condition will not be applied on this element set."; } -void SinglePhaseReactiveTransport::applyPresSpeciesDirichletBC( real64 const time_n, - real64 const dt, - DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const +void SinglePhaseReactiveTransport::applyDirichletBC( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const { FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); @@ -1005,7 +994,7 @@ void SinglePhaseReactiveTransport::applySystemSolution( DofManager const & dofMa void SinglePhaseReactiveTransport::saveConvergedState( ElementSubRegionBase & subRegion ) const { - FlowSolverBase::saveConvergedState( subRegion ); + SinglePhaseBase::saveConvergedState( subRegion ); arrayView2d< real64 const, compflow::USD_COMP > const totalPrimarySpeciesAmount = subRegion.template getField< fields::flow::totalPrimarySpeciesAmount >(); arrayView2d< real64, compflow::USD_COMP > const totalPrimarySpeciesAmount_n = subRegion.template getField< fields::flow::totalPrimarySpeciesAmount_n >(); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index e560c2ddc05..61aa4732fff 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -28,6 +28,8 @@ #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluidUpdateKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ResidualNormKernel.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp" #include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" @@ -180,13 +182,13 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase * @param localMatrix local system matrix * @param localRhs local system right-hand side vector */ - void - applyPresSpeciesDirichletBC( real64 const time_n, - real64 const dt, - DomainPartition & domain, - DofManager const & dofManager, - CRSMatrixView< real64, globalIndex const > const & localMatrix, - arrayView1d< real64 > const & localRhs ) const; + virtual void + applyDirichletBC( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const override; /** * @brief Utility function that encapsulates the call to FieldSpecificationBase::applyFieldValue in BC application diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp index 343fd32b68f..b205f7b9842 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp @@ -53,6 +53,7 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU using Base::m_elemGhostRank; using Base::m_localMatrix; using Base::m_localRhs; + using Base::m_dMass; /// Note: Derivative lineup only supports dP & dT, not component terms using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 0 >; @@ -87,7 +88,7 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // m_dDensity_dLogPrimaryConc( fluid.dDensity_dLogPrimaryConc() ), // m_dPoro_dLogPrimaryConc( solid.getDporosity_dLogPrimaryConc() ), m_primarySpeciesAggregateConcentration( fluid.primarySpeciesAggregateConcentration() ), - // m_dTotalPrimarySpeciesConcentration_dPres( fluid.dTotalPrimarySpeciesConcentration_dPres() ), + // m_dPrimarySpeciesAggregateConcentration_dPres( fluid.dPrimarySpeciesAggregateConcentration_dPres() ), m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc( fluid.dPrimarySpeciesAggregateConcentration_dLogPrimaryConc() ), m_kineticReactionRates( fluid.kineticReactionRates() ), // m_dPrimarySpeciesTotalKineticRate_dPres( fluid.dPrimarySpeciesTotalKineticRate_dPres() ), @@ -150,30 +151,25 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU /** * @brief Compute the local accumulation contributions to the residual and Jacobian - * @tparam FUNC the type of the function that can be used to customize the kernel * @param[in] ei the element index * @param[inout] stack the stack variables * @param[in] kernelOp the function used to customize the kernel */ - template< typename FUNC = NoOpFunc > GEOS_HOST_DEVICE void computeAccumulation( localIndex const ei, - StackVariables & stack, - FUNC && kernelOp = NoOpFunc{} ) const + StackVariables & stack ) const { // Residual[is] += (totalPrimarySpeciesConcentration[is] * stack.poreVolume - totalPrimarySpeciesAmount_n[is]) // - dt * m_volume * primarySpeciesKineticRate[is] // To Check: what's the unit of the kinetic rate Base::computeAccumulation( ei, stack ); - // Base::computeAccumulation( ei, stack, [&] () - // { + + // Step 1: assemble the derivatives of the total mass equation w.r.t log of primary species concentration // for( integer is = 0; is < numSpecies; ++is ) // { - // // Step 1: assemble the derivatives of the total mass equation w.r.t log of primary species concentration // stack.localJacobian[0][is+numDof-numSpecies] = stack.poreVolume * m_dDensity_dLogPrimaryConc[ei][is] + // stack.dPoreVolume_dLogPrimaryConc[is] * m_density[ei][0]; // } - // } ); arraySlice2d< real64 const, compflow::USD_COMP_DC - 1 > dPrimarySpeciesAggregateConcentration_dLogPrimaryConc = m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc[ei]; @@ -216,8 +212,6 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // dPrimarySpeciesTotalKineticRate_dLogPrimaryConc[is][js]; } } - - kernelOp(); // To add thermal dependency } /** @@ -268,8 +262,8 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // View on the total concentration of ions that contain the primary species arrayView2d< real64 const, compflow::USD_COMP > m_primarySpeciesAggregateConcentration; - // // View on the derivatives of total ion concentration for the primary species wrt pressure - // arrayView2d< real64 const, compflow::USD_COMP > m_dTotalPrimarySpeciesConcentration_dPres; + // // View on the derivatives of aggregate concentration for the primary species wrt pressure + // arrayView2d< real64 const, compflow::USD_COMP > m_dPrimarySpeciesAggregateConcentration_dPres; // View on the derivatives of total ion concentration for the primary species wrt log of primary species concentration arrayView3d< real64 const, compflow::USD_COMP_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp index 25ce6abfd7c..9902addd22f 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp @@ -39,12 +39,13 @@ namespace singlePhaseReactiveFVMKernels /** * @class FluxComputeKernel * @tparam NUM_SPECIES number of fluid primary species + * @tparam NUM_EQN number of equations * @tparam NUM_DOF number of degrees of freedom * @tparam STENCILWRAPPER the type of the stencil wrapper * @brief Define the interface for the assembly kernel in charge of flux terms */ -template< integer NUM_SPECIES, integer NUM_DOF, typename STENCILWRAPPER > -class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_SPECIES+1, NUM_DOF, STENCILWRAPPER > +template< integer NUM_SPECIES, integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER > +class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER > { public: @@ -77,7 +78,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S using AbstractBase::m_dens; using AbstractBase::m_dDens; - using Base = singlePhaseFVMKernels::FluxComputeKernel< NUM_SPECIES+1, NUM_DOF, STENCILWRAPPER >; + using Base = singlePhaseFVMKernels::FluxComputeKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >; using Base::numDof; using Base::numEqn; using Base::maxNumElems; @@ -112,8 +113,13 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S * @param[in] stencilWrapper reference to the stencil wrapper * @param[in] dofNumberAccessor * @param[in] singlePhaseFlowAccessors + * @param[in] reactiveSinglePhaseFlowAccessors * @param[in] singlePhaseFluidAccessors + * @param[in] reactiveSinglePhaseFluidAccessors * @param[in] permeabilityAccessors + * @param[in] diffusionAccessors + * @param[in] porosityAccessors + * @param[in] hasDiffusion the flag to turn on diffusion calculation * @param[in] dt time step size * @param[inout] localMatrix the local CRS matrix * @param[inout] localRhs the local right-hand side vector @@ -213,9 +219,11 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S real64 const & fluxVal, real64 const (&dFlux_dP)[2] ) { - GEOS_UNUSED_VAR( connectionIndex, alpha, mobility ); // Step 1: compute the derivatives of the fluid density, potential difference, // and the massFlux wrt log of primary species concentration (to complete) + real64 dFlux_dLogConc[numFluxSupportPoints][numSpecies]{}; + + GEOS_UNUSED_VAR( dFlux_dLogConc ); // Todo: to add the massFlux derivatives wrt speciesConc // Step 2: compute the speciesFlux real64 speciesFlux[numSpecies]{}; @@ -233,7 +241,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S real64 const fluidDens_up = m_dens[er_up][esr_up][ei_up][0]; real64 const dDens_dPres = m_dDens[er_up][esr_up][ei_up][0][DerivOffset::dP]; - // compute species fluxes and derivatives using upstream cell composition + // compute species fluxes and derivatives using upstream cell concentration for( integer is = 0; is < numSpecies; ++is ) { real64 const aggregateConc_i = m_primarySpeciesAggregateConc[er_up][esr_up][ei_up][is]; @@ -256,8 +264,8 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S /// populate local flux vector and derivatives for( integer is = 0; is < numSpecies; ++is ) { - integer const eqIndex0 = k[0] * numEqn + is + 1; - integer const eqIndex1 = k[1] * numEqn + is + 1; + integer const eqIndex0 = k[0] * numEqn + numEqn - numSpecies + is; + integer const eqIndex1 = k[1] * numEqn + numEqn - numSpecies + is; stack.localFlux[eqIndex0] += m_dt * speciesFlux[is]; stack.localFlux[eqIndex1] -= m_dt * speciesFlux[is]; @@ -270,7 +278,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S for( integer js = 0; js < numSpecies; ++js ) { - localIndex const localDofIndexSpecies = localDofIndexPres + js + 1; + localIndex const localDofIndexSpecies = localDofIndexPres + js + numDof - numSpecies; stack.localFluxJacobian[eqIndex0][localDofIndexSpecies] += m_dt * dSpeciesFlux_dLogConc[ke][is][js]; stack.localFluxJacobian[eqIndex1][localDofIndexSpecies] -= m_dt * dSpeciesFlux_dLogConc[ke][is][js]; } @@ -278,14 +286,28 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S } // Customize the kernel with this lambda - kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP ); + kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, fluidDens_up ); } ); + } - // ***************************************************** - // Computation of the diffusion term in the species flux - + /** + * @brief Compute the local diffusion contributions to the residual and Jacobian + * @tparam FUNC the type of the function that can be used to customize the computation of the flux + * @param[in] iconn the connection index + * @param[inout] stack the stack variables + * @param[in] NoOpFunc the function used to customize the computation of the flux + */ + template< typename FUNC = NoOpFunc > + GEOS_HOST_DEVICE + void computeDiffusion( localIndex const iconn, + StackVariables & stack, + FUNC && kernelOp = NoOpFunc{} ) const + { if( m_hasDiffusion ) { + // ***************************************************** + // Computation of the diffusion term in the species flux + // Step 1: compute the diffusion transmissibilities at this face m_stencilWrapper.computeWeights( iconn, m_diffusivity, @@ -306,6 +328,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S // clear working arrays real64 diffusionFlux[numSpecies]{}; + real64 speciesGrad[numSpecies]{}; // real64 dDiffusionFlux_dP[numFluxSupportPoints][numSpecies]{}; // Turn on if diffusionFlux is pressure-dependent real64 dDiffusionFlux_dLogConc[numFluxSupportPoints][numSpecies][numSpecies]{}; @@ -316,7 +339,6 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S // loop over primary species for( integer is = 0; is < numSpecies; ++is ) { - real64 speciesGrad_i = 0.0; // real64 dSpeciesGrad_i_dP[numFluxSupportPoints]{}; // Turn on if speciesGrad is pressure-dependent real64 dSpeciesGrad_i_dLogConc[numFluxSupportPoints][numSpecies]{}; @@ -329,7 +351,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S real64 const aggregateConc_i = m_primarySpeciesAggregateConc[er][esr][ei][is]; - speciesGrad_i += diffusionTrans[ke] * aggregateConc_i; + speciesGrad[is] += diffusionTrans[ke] * aggregateConc_i; for( integer js = 0; js < numSpecies; ++js ) { @@ -340,14 +362,14 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S } // choose upstream cell for species upwinding - localIndex const k_up = (speciesGrad_i >= 0) ? 0 : 1; + localIndex const k_up = (speciesGrad[is] >= 0) ? 0 : 1; localIndex const er_up = seri[k_up]; localIndex const esr_up = sesri[k_up]; localIndex const ei_up = sei[k_up]; // computation of the upwinded species flux - diffusionFlux[is] += m_referencePorosity[er_up][esr_up][ei_up] * speciesGrad_i; + diffusionFlux[is] += m_referencePorosity[er_up][esr_up][ei_up] * speciesGrad[is]; // add contributions of the derivatives of component fractions wrt pressure/component fractions for( integer ke = 0; ke < numFluxSupportPoints; ke++ ) @@ -357,14 +379,10 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S dDiffusionFlux_dLogConc[ke][is][js] += m_referencePorosity[er_up][esr_up][ei_up] * dSpeciesGrad_i_dLogConc[ke][js]; } } - } // loop over primary species - // Add the local diffusion flux contribution to the residual and Jacobian - // loop over primary species - for( integer is = 0; is < numSpecies; ++is ) - { - integer const eqIndex0 = k[0] * numEqn + is + 1; - integer const eqIndex1 = k[1] * numEqn + is + 1; + // Add the local diffusion flux contribution to the residual and Jacobian + integer const eqIndex0 = k[0] * numEqn + numEqn - numSpecies + is; + integer const eqIndex1 = k[1] * numEqn + numEqn - numSpecies + is; stack.localFlux[eqIndex0] += m_dt * diffusionFlux[is]; stack.localFlux[eqIndex1] -= m_dt * diffusionFlux[is]; @@ -377,13 +395,15 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S for( integer js = 0; js < numSpecies; ++js ) { - localIndex const localDofIndexComp = localDofIndexPres + js + 1; - stack.localFluxJacobian[eqIndex0][localDofIndexComp] += m_dt * dDiffusionFlux_dLogConc[ke][is][js]; - stack.localFluxJacobian[eqIndex1][localDofIndexComp] -= m_dt * dDiffusionFlux_dLogConc[ke][is][js]; + localIndex const localDofIndexSpecies = localDofIndexPres + js + numDof - numSpecies; + stack.localFluxJacobian[eqIndex0][localDofIndexSpecies] += m_dt * dDiffusionFlux_dLogConc[ke][is][js]; + stack.localFluxJacobian[eqIndex1][localDofIndexSpecies] -= m_dt * dDiffusionFlux_dLogConc[ke][is][js]; } } - } + // Customize the kernel with this lambda + kernelOp( is, k, seri, sesri, sei, connectionIndex, k_up ); + } // loop over primary species connectionIndex++; } } @@ -395,9 +415,11 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S * @param[in] iconn the connection index * @param[inout] stack the stack variables */ + template< typename FUNC = NoOpFunc > GEOS_HOST_DEVICE void complete( localIndex const iconn, - StackVariables & stack ) const + StackVariables & stack, + FUNC && kernelOp = NoOpFunc{} ) const { // Call Base::complete to assemble the total mass balance equation // In the lambda, add contribution to residual and jacobian into the species amount balance equation @@ -407,14 +429,43 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S // The no. of fluxes is equal to the no. of equations in m_localRhs and m_localMatrix for( integer is = 0; is < numSpecies; ++is ) { - RAJA::atomicAdd( parallelDeviceAtomic{}, &AbstractBase::m_localRhs[localRow + is + 1], - stack.localFlux[i * numEqn + is + 1] ); + RAJA::atomicAdd( parallelDeviceAtomic{}, &AbstractBase::m_localRhs[localRow + numEqn - numSpecies + is], + stack.localFlux[i * numEqn + numEqn - numSpecies + is] ); AbstractBase::m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic > - ( localRow + is + 1, + ( localRow + numEqn - numSpecies + is, stack.dofColIndices.data(), - stack.localFluxJacobian[i * numEqn + is + 1].dataIfContiguous(), + stack.localFluxJacobian[i * numEqn + numEqn - numSpecies + is].dataIfContiguous(), stack.stencilSize * numDof ); } + + // call the lambda to assemble additional terms, such as thermal terms + kernelOp( i, localRow ); + } ); + } + + /** + * @brief Performs the kernel launch + * @tparam POLICY the policy used in the RAJA kernels + * @tparam KERNEL_TYPE the kernel type + * @param[in] numConnections the number of connections + * @param[inout] kernelComponent the kernel component providing access to setup/compute/complete functions and stack variables + */ + template< typename POLICY, typename KERNEL_TYPE > + static void + launch( localIndex const numConnections, + KERNEL_TYPE const & kernelComponent ) + { + GEOS_MARK_FUNCTION; + + forAll< POLICY >( numConnections, [=] GEOS_HOST_DEVICE ( localIndex const iconn ) + { + typename KERNEL_TYPE::StackVariables stack( kernelComponent.stencilSize( iconn ), + kernelComponent.numPointsInFlux( iconn ) ); + + kernelComponent.setup( iconn, stack ); + kernelComponent.computeFlux( iconn, stack ); + kernelComponent.computeDiffusion( iconn, stack ); + kernelComponent.complete( iconn, stack ); } ); } @@ -429,7 +480,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_S /// Views on primary species aggregate concentration ElementViewConst< arrayView2d< real64 const, compflow::USD_COMP > > const m_primarySpeciesAggregateConc; - /// Views on primary species aggregate concentration + /// Views on the derivative of primary species aggregate concentration wrt log of primary concentration ElementViewConst< arrayView3d< real64 const, compflow::USD_COMP_DC > > const m_dPrimarySpeciesAggregateConc_dLogPrimaryConc; /// Views on diffusivity @@ -482,12 +533,13 @@ class FluxComputeKernelFactory { integer constexpr NUM_SPECIES = NS(); integer constexpr NUM_DOF = 1+NS(); + integer constexpr NUM_EQN = 1+NS(); ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > > dofNumberAccessor = elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); - using KernelType = FluxComputeKernel< NUM_SPECIES, NUM_DOF, STENCILWRAPPER >; + using KernelType = FluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, STENCILWRAPPER >; typename KernelType::SinglePhaseFlowAccessors flowAccessors( elemManager, solverName ); typename KernelType::ReactiveSinglePhaseFlowAccessors reactiveFlowAccessors( elemManager, solverName ); typename KernelType::SinglePhaseFluidAccessors fluidAccessors( elemManager, solverName ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp new file mode 100644 index 00000000000..8911ddde9b9 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp @@ -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. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file ThermalAccumulationKernels.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_THERMALACCUMULATIONKERNELS_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_THERMALACCUMULATIONKERNELS_HPP + +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp" + +namespace geos +{ + +namespace thermalSinglePhaseReactiveBaseKernels +{ + +/******************************** AccumulationKernel ********************************/ + +/** + * @class AccumulationKernel + * @brief Define the interface for the assembly kernel in charge of accumulation + */ +template< typename SUBREGION_TYPE, integer NUM_DOF, integer NUM_SPECIES > +class AccumulationKernel : public singlePhaseReactiveBaseKernels::AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES > +{ + +public: + + using Base = singlePhaseReactiveBaseKernels::AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES >; + using Base::numDof; + using Base::numEqn; + using Base::numSpecies; + using Base::m_rankOffset; + using Base::m_dofNumber; + using Base::m_elemGhostRank; + using Base::m_localMatrix; + using Base::m_localRhs; + using Base::m_dMass; + using Base::m_volume; + using Base::m_deltaVolume; + using Base::m_primarySpeciesAggregateConcentration; + + /// Note: Derivative lineup only supports dP & dT, not component terms + using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; + /** + * @brief Constructor + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofKey the string key to retrieve the degress of freedom numbers + * @param[in] subRegion the element subregion + * @param[in] fluid the fluid model + * @param[in] solid the solid model + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + AccumulationKernel( globalIndex const rankOffset, + string const dofKey, + SUBREGION_TYPE const & subRegion, + constitutive::ReactiveSingleFluid const & fluid, + constitutive::CoupledSolidBase const & solid, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + : Base( rankOffset, dofKey, subRegion, fluid, solid, dt, localMatrix, localRhs ), + m_energy( subRegion.template getField< fields::flow::energy >() ), + m_energy_n( subRegion.template getField< fields::flow::energy_n >() ), + m_dEnergy( subRegion.template getField< fields::flow::dEnergy >() ), + m_dPoro_dTemp( solid.getDporosity_dTemperature() ) + // m_dPrimarySpeciesAggregateConcentration_dTemp( fluid.dPrimarySpeciesAggregateConcentration_dTemp() ), + // m_dPrimarySpeciesTotalKineticRate_dTemp( fluid.dPrimarySpeciesTotalKineticRate_dTemp() ), + {} + + /** + * @struct StackVariables + * @brief Kernel variables (dof numbers, jacobian and residual) located on the stack + */ + struct StackVariables : public Base::StackVariables + { +public: + + GEOS_HOST_DEVICE + StackVariables() + : Base::StackVariables() + {} + + using Base::StackVariables::localRow; + using Base::StackVariables::dofIndices; + using Base::StackVariables::localResidual; + using Base::StackVariables::localJacobian; + using Base::StackVariables::poreVolume; + using Base::StackVariables::dPoreVolume_dLogPrimaryConc; + + // Pore volume information + + /// Derivative of pore volume with respect to temperature + real64 dPoreVolume_dTemp = 0.0; + }; + + /** + * @brief Performs the setup phase for the kernel. + * @param[in] ei the element index + * @param[in] stack the stack variables + */ + GEOS_HOST_DEVICE + void setup( localIndex const ei, + StackVariables & stack ) const + { + Base::setup( ei, stack ); + + stack.dPoreVolume_dTemp = ( m_volume[ei] + m_deltaVolume[ei] ) * m_dPoro_dTemp[ei][0]; + } + + /** + * @brief Compute the local accumulation contributions to the residual and Jacobian + * @param[in] ei the element index + * @param[inout] stack the stack variables + * @param[in] kernelOp the function used to customize the kernel + */ + GEOS_HOST_DEVICE + void computeAccumulation( localIndex const ei, + StackVariables & stack ) const + { + Base::computeAccumulation( ei, stack ); + + // Step 1: assemble the derivatives of the mass balance equation w.r.t temperature + stack.localJacobian[0][numDof-numSpecies-1] = m_dMass[ei][DerivOffset::dT]; + + // Step 2: assemble the accumulation term of the energy equation + // Step 2.1: assemble the residual and derivatives wrt pressure and temperature + stack.localResidual[numEqn-numSpecies-1] = m_energy[ei] - m_energy_n[ei]; + stack.localJacobian[numEqn-numSpecies-1][0] += m_dEnergy[ei][DerivOffset::dP]; + stack.localJacobian[numEqn-numSpecies-1][numDof-numSpecies-1] += m_dEnergy[ei][DerivOffset::dT]; + + // Step 2.2: assemble the derivatives of the energy equation w.r.t log primary species concentration + // for( integer is = 0; is < numSpecies; ++is ) + // { + // stack.localJacobian[numEqn-numSpecies-1][is+numDof-numSpecies] += stack.dPoreVolume_dLogPrimaryConc[is] * m_density[ei][0] * + // m_fluidInternalEnergy[ei][0] + // - stack.dPoreVolume_dLogPrimaryConc[is] * + // m_rockInternalEnergy[ei][0] + // + stack.poreVolume * m_dDensity_dLogPrimaryConc[ei][is] * + // m_fluidInternalEnergy[ei][0] + // + stack.poreVolume * m_density[ei][0] * + // m_dFluidInternalEnergy_dLogPrimaryConc[ei][is]; + // } + + // Step 3: assemble the derivatives of the species amount balance equation w.r.t temperature + for( integer is = 0; is < numSpecies; ++is ) + { + // Drivative of primary species amount in pore volume wrt temperature + stack.localJacobian[is+numEqn-numSpecies][numDof-numSpecies-1] += stack.dPoreVolume_dTemp * m_primarySpeciesAggregateConcentration[ei][is] + /* + stack.poreVolume * + m_dPrimarySpeciesAggregateConcentration_dTemp[ei][is] */; + // // Derivative of reaction term wrt temperature + // stack.localJacobian[is+numEqn-numSpecies][numDof-numSpecies-1] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * + // m_dPrimarySpeciesTotalKineticRate_dTemp[is]; + } + } + + /** + * @brief Performs the complete phase for the kernel. + * @param[in] ei the element index + * @param[inout] stack the stack variables + */ + GEOS_HOST_DEVICE + void complete( localIndex const ei, + StackVariables & stack ) const + { + // Step 1: assemble the total mass balance equation (i = 0) + // and species amount balance equation (i = numEqn-numSpecies to i = numEqn-1) + Base::complete( ei, stack ); + + // Step 2: assemble the energy equation (i = numEqn-numSpecies-1) + m_localRhs[stack.localRow + numEqn-numSpecies-1] += stack.localResidual[numEqn-numSpecies-1]; + m_localMatrix.template addToRow< serialAtomic >( stack.localRow + numEqn-numSpecies-1, + stack.dofIndices, + stack.localJacobian[numEqn-numSpecies-1], + numDof ); + } + +protected: + + /// View on energy + arrayView1d< real64 const > const m_energy; + arrayView1d< real64 const > const m_energy_n; + arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const m_dEnergy; + + /// Views on the porosity derivative + arrayView2d< real64 const > const m_dPoro_dTemp; + + // // View on the derivatives of aggregate concentration for the primary species wrt temperature + // arrayView2d< real64 const, compflow::USD_COMP > m_dPrimarySpeciesAggregateConcentration_dTemp; + + // // View on the derivatives of total kinetic rate of primary species wrt temperature + // arrayView2d< real64 const, compflow::USD_COMP > m_dPrimarySpeciesTotalKineticRate_dTemp; + +}; + +/** + * @class AccumulationKernelFactory + */ +class AccumulationKernelFactory +{ +public: + + /** + * @brief Create a new kernel and launch + * @tparam POLICY the policy used in the RAJA kernel + * @param[in] numSpecies the number of primary species + * @param[in] dt time step + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofKey the string key to retrieve the degress of freedom numbers + * @param[in] subRegion the element subregion + * @param[in] fluid the fluid model + * @param[in] solid the solid model + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + template< typename POLICY, typename SUBREGION_TYPE > + static void + createAndLaunch( integer const numSpecies, + real64 const dt, + globalIndex const rankOffset, + string const dofKey, + SUBREGION_TYPE const & subRegion, + constitutive::ReactiveSingleFluid const & fluid, + constitutive::CoupledSolidBase const & solid, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + singlePhaseReactiveBaseKernels:: + internal::kernelLaunchSelectorCompSwitch( numSpecies, [&] ( auto NS ) + { + integer constexpr NUM_SPECIES = NS(); + integer constexpr NUM_DOF = 2+NS(); + AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES > kernel( rankOffset, dofKey, subRegion, fluid, solid, dt, localMatrix, localRhs ); + AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES >::template launch< POLICY >( subRegion.size(), kernel ); + } ); + } +}; + +} // namespace thermalSinglePhaseReactiveBaseKernels + +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_THERMALACCUMULATIONKERNELS_HPP diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp new file mode 100644 index 00000000000..a61571baea6 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp @@ -0,0 +1,628 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ThermalFluxComputeKernel.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_THERMALFLUXCOMPUTEKERNEL_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_THERMALFLUXCOMPUTEKERNEL_HPP + +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp" + +#include "constitutive/thermalConductivity/SinglePhaseThermalConductivityBase.hpp" +#include "constitutive/thermalConductivity/ThermalConductivityFields.hpp" + +namespace geos +{ + +namespace thermalSinglePhaseReactiveFVMKernels +{ +/******************************** FluxComputeKernel ********************************/ + +/** + * @class FluxComputeKernel + * @tparam NUM_SPECIES number of fluid primary species + * @tparam NUM_EQN number of equations + * @tparam NUM_DOF number of degrees of freedom + * @tparam STENCILWRAPPER the type of the stencil wrapper + * @brief Define the interface for the assembly kernel in charge of flux terms + */ +template< integer NUM_SPECIES, integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER > +class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, STENCILWRAPPER > +{ +public: + + /** + * @brief The type for element-based data. Consists entirely of ArrayView's. + * + * Can be converted from ElementRegionManager::ElementViewConstAccessor + * by calling .toView() or .toViewConst() on an accessor instance + */ + template< typename VIEWTYPE > + using ElementViewConst = ElementRegionManager::ElementViewConst< VIEWTYPE >; + + using AbstractBase = singlePhaseFVMKernels::FluxComputeKernelBase; + using DofNumberAccessor = AbstractBase::DofNumberAccessor; + using SinglePhaseFlowAccessors = AbstractBase::SinglePhaseFlowAccessors; + using SinglePhaseFluidAccessors = AbstractBase::SinglePhaseFluidAccessors; + using PermeabilityAccessors = AbstractBase::PermeabilityAccessors; + + using AbstractBase::m_dt; + using AbstractBase::m_rankOffset; + using AbstractBase::m_dofNumber; + using AbstractBase::m_gravCoef; + using AbstractBase::m_mob; + using AbstractBase::m_dMob; + using AbstractBase::m_dens; + using AbstractBase::m_dDens; + + using Base = singlePhaseReactiveFVMKernels::FluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, STENCILWRAPPER >; + using ReactiveSinglePhaseFlowAccessors = typename Base::ReactiveSinglePhaseFlowAccessors; + using ReactiveSinglePhaseFluidAccessors = typename Base::ReactiveSinglePhaseFluidAccessors; + using DiffusionAccessors = typename Base::DiffusionAccessors; + using PorosityAccessors = typename Base::PorosityAccessors; + using Base::numSpecies; + using Base::numFluxSupportPoints; + using Base::numDof; + using Base::numEqn; + using Base::maxNumElems; + using Base::maxNumConns; + using Base::maxStencilSize; + using Base::m_stencilWrapper; + using Base::m_seri; + using Base::m_sesri; + using Base::m_sei; + using Base::m_primarySpeciesAggregateConc; + using Base::m_referencePorosity; + + using ThermalSinglePhaseFlowAccessors = + StencilAccessors< fields::flow::temperature >; + + using ThermalReactiveSinglePhaseFluidAccessors = + StencilMaterialAccessors< constitutive::ReactiveSingleFluid, + fields::singlefluid::enthalpy, + fields::singlefluid::dEnthalpy >; + + using ThermalConductivityAccessors = + StencilMaterialAccessors< constitutive::SinglePhaseThermalConductivityBase, + fields::thermalconductivity::effectiveConductivity, + fields::thermalconductivity::dEffectiveConductivity_dT >; + + + /** + * @brief Constructor for the kernel interface + * @param[in] rankOffset the offset of my MPI rank + * @param[in] stencilWrapper reference to the stencil wrapper + * @param[in] dofNumberAccessor accessor for the dofs numbers + * @param[in] singlePhaseFlowAccessors accessor for wrappers registered by the solver + * @param[in] reactiveSinglePhaseFlowAccessors accessor for *reactive* wrappers registered by the solver + * @param[in] thermalSinglePhaseFlowAccessors accessor for *thermal* wrappers registered by the solver + * @param[in] singlePhaseFluidAccessors accessor for wrappers registered by the single fluid model + * @param[in] reactiveSinglePhaseFluidAccessors accessor for *reactive* wrappers registered by the single fluid model + * @param[in] thermalReactiveSinglePhaseFluidAccessors accessor for *thermal reactive* wrappers registered by the single fluid model + * @param[in] permeabilityAccessors accessor for wrappers registered by the permeability model + * @param[in] diffusionAccessors accessor for wrappers registered by the diffusion model + * @param[in] porosityAccessors accessor for wrappers registered by the porosity model + * @param[in] thermalConductivityAccessors accessor for wrappers registered by the thermal conductivity model + * @param[in] hasDiffusion the flag to turn on diffusion calculation + * @param[in] dt time step size + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + FluxComputeKernel( globalIndex const rankOffset, + STENCILWRAPPER const & stencilWrapper, + DofNumberAccessor const & dofNumberAccessor, + SinglePhaseFlowAccessors const & singlePhaseFlowAccessors, + ReactiveSinglePhaseFlowAccessors const & reactiveSinglePhaseFlowAccessors, + ThermalSinglePhaseFlowAccessors const & thermalSinglePhaseFlowAccessors, + SinglePhaseFluidAccessors const & singlePhaseFluidAccessors, + ReactiveSinglePhaseFluidAccessors const & reactiveSinglePhaseFluidAccessors, + ThermalReactiveSinglePhaseFluidAccessors const & thermalReactiveSinglePhaseFluidAccessors, + PermeabilityAccessors const & permeabilityAccessors, + DiffusionAccessors const & diffusionAccessors, + PorosityAccessors const & porosityAccessors, + ThermalConductivityAccessors const & thermalConductivityAccessors, + integer const & hasDiffusion, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + : Base( rankOffset, + stencilWrapper, + dofNumberAccessor, + singlePhaseFlowAccessors, + reactiveSinglePhaseFlowAccessors, + singlePhaseFluidAccessors, + reactiveSinglePhaseFluidAccessors, + permeabilityAccessors, + diffusionAccessors, + porosityAccessors, + hasDiffusion, + dt, + localMatrix, + localRhs ), + m_temp( thermalSinglePhaseFlowAccessors.get( fields::flow::temperature {} ) ), + m_enthalpy( thermalReactiveSinglePhaseFluidAccessors.get( fields::singlefluid::enthalpy {} ) ), + m_dEnthalpy( thermalReactiveSinglePhaseFluidAccessors.get( fields::singlefluid::dEnthalpy {} ) ), + // m_dPrimarySpeciesAggregateConcentration_dTemp( fluid.dPrimarySpeciesAggregateConcentration_dTemp() ), + m_thermalConductivity( thermalConductivityAccessors.get( fields::thermalconductivity::effectiveConductivity {} ) ), + m_dThermalCond_dT( thermalConductivityAccessors.get( fields::thermalconductivity::dEffectiveConductivity_dT {} ) ) + {} + + struct StackVariables : public Base::StackVariables + { +public: + + GEOS_HOST_DEVICE + StackVariables( localIndex const size, localIndex numElems ) + : Base::StackVariables( size, numElems ), + energyFlux( 0.0 ), + dEnergyFlux_dP( size ), + dEnergyFlux_dT( size ) + {} + + using Base::StackVariables::stencilSize; + using Base::StackVariables::numFluxElems; + using Base::StackVariables::transmissibility; + using Base::StackVariables::dTrans_dPres; + using Base::StackVariables::dofColIndices; + using Base::StackVariables::localFlux; + using Base::StackVariables::localFluxJacobian; + using Base::StackVariables::diffusionTransmissibility; + using Base::StackVariables::dDiffusionTrans_dT; + + + // Thermal transmissibility + real64 thermalTransmissibility[maxNumConns][2]{}; + + /// Derivatives of thermal transmissibility with respect to temperature + real64 dThermalTrans_dT[maxNumConns][2]{}; + + // Energy fluxes and derivatives + + /// Energy fluxes + real64 energyFlux; + /// Derivatives of energy fluxes wrt pressure + stackArray1d< real64, maxStencilSize > dEnergyFlux_dP; + /// Derivatives of energy fluxes wrt temperature + stackArray1d< real64, maxStencilSize > dEnergyFlux_dT; + + }; + + /** + * @brief Compute the local flux contributions to the residual and Jacobian + * @param[in] iconn the connection index + * @param[inout] stack the stack variables + */ + GEOS_HOST_DEVICE + void computeFlux( localIndex const iconn, + StackVariables & stack ) const + { + using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; + // *********************************************** + // First, we call the base computeFlux to compute: + // 1) massFlux and speciesFlux and their derivatives (including derivatives wrt temperature), + // 2) enthalpy part of energyFlux and its derivatives (including derivatives wrt temperature) + // + // Computing dFlux_dT and the enthalpy flux requires quantities already computed in the base computeFlux, + // such as potGrad, fluxVal, and the indices of the upwind cell + // We use the lambda below (called **inside** the phase loop of the base computeFlux) to access these variables + Base::computeFlux( iconn, stack, [&] ( localIndex const (&k)[2], + localIndex const (&seri)[2], + localIndex const (&sesri)[2], + localIndex const (&sei)[2], + localIndex const connectionIndex, + real64 const alpha, + real64 const mobility, + real64 const & potGrad, + real64 const & fluxVal, + real64 const (&dFlux_dP)[2], + real64 const fluidDens_up ) + { + // Step 1: compute the derivatives of the (upwinded) massFlux wrt temperature + // -------------------------------------------------------------------------- + // Step 1.1: compute the derivatives of the mean density at the interface wrt temperature + real64 dDensMean_dT[numFluxSupportPoints]{0.0, 0.0}; + + real64 const trans[numFluxSupportPoints] = { stack.transmissibility[connectionIndex][0], stack.transmissibility[connectionIndex][1] }; + + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + dDensMean_dT[ke] = 0.5 * m_dDens[seri[ke]][sesri[ke]][sei[ke]][0][DerivOffset::dT]; + } + + // Step 1.2: compute the derivatives of the potential difference wrt temperature + real64 dGravHead_dT[numFluxSupportPoints]{0.0, 0.0}; + + // compute derivative of gravity potential difference wrt temperature + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + localIndex const er = seri[ke]; + localIndex const esr = sesri[ke]; + localIndex const ei = sei[ke]; + + real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; + + for( integer i = 0; i < numFluxSupportPoints; ++i ) + { + dGravHead_dT[i] += dDensMean_dT[i] * gravD; + } + } + + real64 dFlux_dT[numFluxSupportPoints]{0.0, 0.0}; + + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + dFlux_dT[ke] -= dGravHead_dT[ke]; + } + + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + dFlux_dT[ke] *= mobility; + } + + // compute the derivatives of the mobility wrt temperature + // *** upwinding *** + real64 dMob_dT[numFluxSupportPoints]{}; + + if( alpha <= 0.0 || alpha >= 1.0 ) + { + localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); + dMob_dT[k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][DerivOffset::dT]; + } + else + { + real64 const mobWeights[numFluxSupportPoints] = { alpha, 1.0 - alpha }; + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + dMob_dT[ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][DerivOffset::dT]; + } + } + + // add contribution from upstream cell mobility derivatives + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + dFlux_dT[ke] += dMob_dT[ke] * potGrad; + } + + // Step 1.3: populate local jacobian + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + localIndex const localDofIndexTemp = k[ke] * numDof + numDof - numSpecies - 1; + stack.localFluxJacobian[k[0]*numEqn][localDofIndexTemp] += m_dt * dFlux_dT[ke]; + stack.localFluxJacobian[k[1]*numEqn][localDofIndexTemp] -= m_dt * dFlux_dT[ke]; + } + + // Step 2: compute the derivatives of the speciesFlux wrt temperature + // ------------------------------------------------------------------- + real64 dSpeciesFlux_dT[numFluxSupportPoints][numSpecies]{}; + + { + // Step 2.1: compute the derivatives of the upstream density wrt temperature + // choose upstream cell + localIndex const k_up = (potGrad >= 0) ? 0 : 1; + + localIndex const er_up = seri[k_up]; + localIndex const esr_up = sesri[k_up]; + localIndex const ei_up = sei[k_up]; + + real64 const dDens_dTemp = m_dDens[er_up][esr_up][ei_up][0][DerivOffset::dT]; + + // Step 2.2: compute speciesFlux derivative wrt temperature + for( integer is = 0; is < numSpecies; ++is ) + { + real64 const aggregateConc_i = m_primarySpeciesAggregateConc[er_up][esr_up][ei_up][is]; + + // real64 const dAggregateConc_i_dTemp = m_dPrimarySpeciesAggregateConcentration_dTemp[er_up][esr_up][ei_up][is]; + // dSpeciesFlux_dT[k_up][is] += dAggregateConc_i_dTemp * fluxVal / fluidDens_up; + dSpeciesFlux_dT[k_up][is] += -aggregateConc_i * fluxVal * dDens_dTemp / (fluidDens_up * fluidDens_up); + + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + dSpeciesFlux_dT[ke][is] += aggregateConc_i / fluidDens_up * dFlux_dT[ke]; + } + } + } + + // Step 2.3: populate local jacobian + for( integer is = 0; is < numSpecies; ++is ) + { + integer const eqIndex0 = k[0] * numEqn + numEqn - numSpecies + is; + integer const eqIndex1 = k[1] * numEqn + numEqn - numSpecies + is; + + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + localIndex const localDofIndexTemp = k[ke] * numDof + numDof - numSpecies - 1; + + stack.localFluxJacobian[eqIndex0][localDofIndexTemp] += m_dt * dSpeciesFlux_dT[ke][is]; + stack.localFluxJacobian[eqIndex1][localDofIndexTemp] -= m_dt * dSpeciesFlux_dT[ke][is]; + } + } + + // Step 3: compute the enthalpy flux + // ---------------------------------- + real64 enthalpy = 0.0; + real64 dEnthalpy_dP[numFluxSupportPoints]{0.0, 0.0}; + real64 dEnthalpy_dT[numFluxSupportPoints]{0.0, 0.0}; + // Todo: to add the enthalpy derivatives wrt speciesConc if needed + // real64 dEnthalpy_dLogConc[numFluxSupportPoints][numSpecies]{}; + + if( alpha <= 0.0 || alpha >= 1.0 ) + { + localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); + + enthalpy = m_enthalpy[seri[k_up]][sesri[k_up]][sei[k_up]][0]; + dEnthalpy_dP[k_up] = m_dEnthalpy[seri[k_up]][sesri[k_up]][sei[k_up]][0][DerivOffset::dP]; + dEnthalpy_dT[k_up] = m_dEnthalpy[seri[k_up]][sesri[k_up]][sei[k_up]][0][DerivOffset::dT]; + } + else + { + real64 const mobWeights[numFluxSupportPoints] = { alpha, 1.0 - alpha }; + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + enthalpy += mobWeights[ke] * m_enthalpy[seri[ke]][sesri[ke]][sei[ke]][0]; + dEnthalpy_dP[ke] = mobWeights[ke] * m_dEnthalpy[seri[ke]][sesri[ke]][sei[ke]][0][DerivOffset::dP]; + dEnthalpy_dT[ke] = mobWeights[ke] * m_dEnthalpy[seri[ke]][sesri[ke]][sei[ke]][0][DerivOffset::dT]; + } + } + + stack.energyFlux += fluxVal * enthalpy; + + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + stack.dEnergyFlux_dP[ke] += dFlux_dP[ke] * enthalpy; + stack.dEnergyFlux_dT[ke] += dFlux_dT[ke] * enthalpy; + } + + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + stack.dEnergyFlux_dP[ke] += fluxVal * dEnthalpy_dP[ke]; + stack.dEnergyFlux_dT[ke] += fluxVal * dEnthalpy_dT[ke]; + } + + } ); + + // ***************************************************** + // Computation of the conduction term in the energy flux + // Note that the enthalpy term in the energy was computed above + // Note that this term is computed using an explicit treatment of conductivity for now + + // Step 1: compute the thermal transmissibilities at this face + // We follow how the thermal compositional multi-phase solver does to update the thermal transmissibility + m_stencilWrapper.computeWeights( iconn, + m_thermalConductivity, + m_dThermalCond_dT, + stack.thermalTransmissibility, + stack.dThermalTrans_dT ); + + localIndex k[numFluxSupportPoints]; + localIndex connectionIndex = 0; + + for( k[0] = 0; k[0] < stack.numFluxElems; ++k[0] ) + { + for( k[1] = k[0] + 1; k[1] < stack.numFluxElems; ++k[1] ) + { + real64 const thermalTrans[numFluxSupportPoints] = { stack.thermalTransmissibility[connectionIndex][0], stack.thermalTransmissibility[connectionIndex][1] }; + real64 const dThermalTrans_dT[numFluxSupportPoints] = { stack.dThermalTrans_dT[connectionIndex][0], stack.dThermalTrans_dT[connectionIndex][1] }; + + localIndex const seri[numFluxSupportPoints] = {m_seri( iconn, k[0] ), m_seri( iconn, k[1] )}; + localIndex const sesri[numFluxSupportPoints] = {m_sesri( iconn, k[0] ), m_sesri( iconn, k[1] )}; + localIndex const sei[numFluxSupportPoints] = {m_sei( iconn, k[0] ), m_sei( iconn, k[1] )}; + + // Step 2: compute temperature difference at the interface + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + localIndex const er = seri[ke]; + localIndex const esr = sesri[ke]; + localIndex const ei = sei[ke]; + + stack.energyFlux += thermalTrans[ke] * m_temp[er][esr][ei]; + stack.dEnergyFlux_dT[ke] += thermalTrans[ke] + dThermalTrans_dT[ke] * m_temp[er][esr][ei]; + } + + integer const eqIndex0 = k[0] * numEqn + numEqn - numSpecies - 1; + integer const eqIndex1 = k[1] * numEqn + numEqn - numSpecies - 1; + + // add energyFlux and its derivatives to localFlux and localFluxJacobian + stack.localFlux[eqIndex0] += m_dt * stack.energyFlux; + stack.localFlux[eqIndex1] -= m_dt * stack.energyFlux; + + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + integer const localDofIndexPres = k[ke] * numDof; + stack.localFluxJacobian[eqIndex0][localDofIndexPres] = m_dt * stack.dEnergyFlux_dP[ke]; + stack.localFluxJacobian[eqIndex1][localDofIndexPres] = -m_dt * stack.dEnergyFlux_dP[ke]; + integer const localDofIndexTemp = localDofIndexPres + numDof - numSpecies - 1; + stack.localFluxJacobian[eqIndex0][localDofIndexTemp] = m_dt * stack.dEnergyFlux_dT[ke]; + stack.localFluxJacobian[eqIndex1][localDofIndexTemp] = -m_dt * stack.dEnergyFlux_dT[ke]; + } + + connectionIndex++; + } + } + } + + /** + * @brief Compute the local flux contributions to the residual and Jacobian + * @param[in] iconn the connection index + * @param[inout] stack the stack variables + */ + GEOS_HOST_DEVICE + void computeDiffusion( localIndex const iconn, + StackVariables & stack ) const + { + Base::computeDiffusion( iconn, stack, [&] ( integer const is, + localIndex const (&k)[2], + localIndex const (&seri)[2], + localIndex const (&sesri)[2], + localIndex const (&sei)[2], + localIndex const connectionIndex, + localIndex const k_up ) + { + real64 dDiffusionFlux_dT[numFluxSupportPoints]{}; + real64 dSpeciesGrad_dT[numFluxSupportPoints]{}; + + // Calculate diffusion derivative wrt temperature + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + localIndex const er = seri[ke]; + localIndex const esr = sesri[ke]; + localIndex const ei = sei[ke]; + + // dSpeciesGrad_dT[ke] += stack.diffusionTransmissibility[connectionIndex][ke] + // * m_dPrimarySpeciesAggregateConcentration_dTemp[er][esr][ei][is]; + + dSpeciesGrad_dT[ke] += stack.dDiffusionTrans_dT[connectionIndex][ke] * m_primarySpeciesAggregateConc[er][esr][ei][is]; + } + + for( integer ke = 0; ke < numFluxSupportPoints; ke++ ) + { + localIndex const er_up = seri[k_up]; + localIndex const esr_up = sesri[k_up]; + localIndex const ei_up = sei[k_up]; + + dDiffusionFlux_dT[ke] += m_referencePorosity[er_up][esr_up][ei_up] * dSpeciesGrad_dT[ke]; + } + + // populate local Jacobian + integer const eqIndex0 = k[0] * numEqn + numEqn - numSpecies + is; + integer const eqIndex1 = k[1] * numEqn + numEqn - numSpecies + is; + + for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) + { + localIndex const localDofIndexTemp = k[ke] * numDof + numDof - numSpecies - 1; + stack.localFluxJacobian[eqIndex0][localDofIndexTemp] += m_dt * dDiffusionFlux_dT[ke]; + stack.localFluxJacobian[eqIndex1][localDofIndexTemp] -= m_dt * dDiffusionFlux_dT[ke]; + } + } ); + } + + /** + * @brief Performs the complete phase for the kernel. + * @param[in] iconn the connection index + * @param[inout] stack the stack variables + */ + GEOS_HOST_DEVICE + void complete( localIndex const iconn, + StackVariables & stack ) const + { + // Call Case::complete to assemble the mass balance equations + // In the lambda, add contribution to residual and jacobian into the energy balance equation + Base::complete( iconn, stack, [&] ( integer const i, + localIndex const localRow ) + { + // The no. of fluxes is equal to the no. of equations in m_localRhs and m_localMatrix + // Different from the one in compositional multi-phase flow, which has a volume balance eqn. + RAJA::atomicAdd( parallelDeviceAtomic{}, &AbstractBase::m_localRhs[localRow + numEqn - numSpecies - 1], stack.localFlux[i * numEqn + numEqn - numSpecies - 1] ); + + AbstractBase::m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >( localRow + numEqn - numSpecies - 1, + stack.dofColIndices.data(), + stack.localFluxJacobian[i * numEqn + numEqn - numSpecies - 1].dataIfContiguous(), + stack.stencilSize * numDof ); + + } ); + } + +protected: + + /// Views on temperature + ElementViewConst< arrayView1d< real64 const > > const m_temp; + + /// Views on enthalpies + ElementViewConst< arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > > const m_enthalpy; + ElementViewConst< arrayView3d< real64 const, constitutive::singlefluid::USD_FLUID_DER > > const m_dEnthalpy; + + // /// Views on the derivative of primary species aggregate concentration wrt temperature + // ElementViewConst< arrayView2d< real64 const, compflow::USD_COMP > > const m_dPrimarySpeciesAggregateConc_dTemp; + + /// View on thermal conductivity + ElementViewConst< arrayView3d< real64 const > > m_thermalConductivity; + + /// View on derivatives of thermal conductivity w.r.t. temperature + ElementViewConst< arrayView3d< real64 const > > m_dThermalCond_dT; + +}; + +/** + * @class FluxComputeKernelFactory + */ +class FluxComputeKernelFactory +{ +public: + + /** + * @brief Create a new kernel and launch + * @tparam POLICY the policy used in the RAJA kernel + * @tparam STENCILWRAPPER the type of the stencil wrapper + * @param[in] numSpecies the number of primary species + * @param[in] hasDiffusion the flag of adding diffusion term + * @param[in] rankOffset the offset of my MPI rank + * @param[in] dofKey string to get the element degrees of freedom numbers + * @param[in] solverName name of the solver (to name accessors) + * @param[in] elemManager reference to the element region manager + * @param[in] stencilWrapper reference to the stencil wrapper + * @param[in] dt time step size + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + template< typename POLICY, typename STENCILWRAPPER > + static void + createAndLaunch( integer const numSpecies, + integer const hasDiffusion, + globalIndex const rankOffset, + string const & dofKey, + string const & solverName, + ElementRegionManager const & elemManager, + STENCILWRAPPER const & stencilWrapper, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + singlePhaseReactiveBaseKernels::internal::kernelLaunchSelectorCompSwitch( numSpecies, [&]( auto NS ) + { + integer constexpr NUM_SPECIES = NS(); + integer constexpr NUM_DOF = 2+NS(); + integer constexpr NUM_EQN = 2+NS(); + + ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > > dofNumberAccessor = + elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); + dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); + + using KernelType = FluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, STENCILWRAPPER >; + typename KernelType::SinglePhaseFlowAccessors flowAccessors( elemManager, solverName ); + typename KernelType::ReactiveSinglePhaseFlowAccessors reactiveFlowAccessors( elemManager, solverName ); + typename KernelType::ThermalSinglePhaseFlowAccessors thermalFlowAccessors( elemManager, solverName ); + typename KernelType::SinglePhaseFluidAccessors fluidAccessors( elemManager, solverName ); + typename KernelType::ReactiveSinglePhaseFluidAccessors reactiveFluidAccessors( elemManager, solverName ); + typename KernelType::ThermalReactiveSinglePhaseFluidAccessors thermalFluidAccessors( elemManager, solverName ); + typename KernelType::PermeabilityAccessors permAccessors( elemManager, solverName ); + typename KernelType::DiffusionAccessors diffusionAccessors( elemManager, solverName ); + typename KernelType::PorosityAccessors porosityAccessors( elemManager, solverName ); + typename KernelType::ThermalConductivityAccessors thermalConductivityAccessors( elemManager, solverName ); + + KernelType kernel( rankOffset, stencilWrapper, dofNumberAccessor, + flowAccessors, reactiveFlowAccessors, thermalFlowAccessors, fluidAccessors, reactiveFluidAccessors, thermalFluidAccessors, + permAccessors, diffusionAccessors, porosityAccessors, thermalConductivityAccessors, + hasDiffusion, dt, localMatrix, localRhs ); + KernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); + } ); + } +}; + +} // namespace thermalSinglePhaseReactiveFVMKernels + +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_THERMALFLUXCOMPUTEKERNEL_HPP From 2b25ae8bb5c08f581f51651ec178bf96862839f1 Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Wed, 2 Apr 2025 14:49:05 -0700 Subject: [PATCH 06/12] feat: add HPCReact as a submodule --- .gitmodules | 3 + .../constitutive/CMakeLists.txt | 17 +++ src/coreComponents/constitutive/HPCReact | 1 + .../reactivefluid/ReactiveFluidLayouts.hpp | 128 ++++++++++++++++ .../ReactiveSinglePhaseFluid.cpp | 91 +++++++++++ .../ReactiveSinglePhaseFluid.hpp | 142 ++++++++++++++++++ 6 files changed, 382 insertions(+) create mode 160000 src/coreComponents/constitutive/HPCReact create mode 100644 src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp create mode 100644 src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp create mode 100644 src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp diff --git a/.gitmodules b/.gitmodules index 5552178f5ce..b2e33109a09 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "src/coreComponents/fileIO/coupling/hdf5_interface"] path = src/coreComponents/fileIO/coupling/hdf5_interface url = ../../GEOS-DEV/hdf5_interface.git +[submodule "src/coreComponents/constitutive/HPCReact"] + path = src/coreComponents/constitutive/HPCReact + url = git@github.com:GEOS-DEV/HPCReact.git diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index 048bc0a2906..c279170d2f1 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -116,6 +116,8 @@ set( constitutive_headers fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.hpp fluid/multifluid/reactive/chemicalReactions/KineticReactions.hpp fluid/multifluid/reactive/chemicalReactions/ReactionsBase.hpp + fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp + fluid/reactivefluid/ReactiveFluidLayouts.hpp fluid/singlefluid/CompressibleSinglePhaseFluid.hpp fluid/singlefluid/ParticleFluid.hpp fluid/singlefluid/ParticleFluidBase.hpp @@ -258,6 +260,7 @@ set( constitutive_sources fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.cpp fluid/multifluid/reactive/chemicalReactions/KineticReactions.cpp fluid/multifluid/reactive/chemicalReactions/ReactionsBase.cpp + fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp fluid/singlefluid/CompressibleSinglePhaseFluid.cpp fluid/singlefluid/ParticleFluid.cpp fluid/singlefluid/ParticleFluidBase.cpp @@ -331,6 +334,20 @@ if( ENABLE_PVTPackage ) list( APPEND dependencyList PVTPackage ) endif() +if (ENABLE_HPCREACT) + set( constitutive_headers + ${constitutive_headers} + fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp + ) + + set( constitutive_sources + ${constitutive_sources} + fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp + ) + add_subdirectory( HPCReact ) + list( APPEND dependencyList hpcReact ) +endif() + geos_decorate_link_dependencies( LIST decoratedDependencies DEPENDENCIES ${dependencyList} ) diff --git a/src/coreComponents/constitutive/HPCReact b/src/coreComponents/constitutive/HPCReact new file mode 160000 index 00000000000..33390bc439b --- /dev/null +++ b/src/coreComponents/constitutive/HPCReact @@ -0,0 +1 @@ +Subproject commit 33390bc439bb0c9d837abdf157df37162451274b diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp new file mode 100644 index 00000000000..a64dfb08dad --- /dev/null +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp @@ -0,0 +1,128 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 Total, S.A + * 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 Layouts.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_LAYOUTS_HPP +#define GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_LAYOUTS_HPP + +#include "common/DataTypes.hpp" +#include "common/GeosxConfig.hpp" + +#include "LvArray/src/typeManipulation.hpp" +#include "RAJA/RAJA.hpp" + +namespace geos +{ +namespace constitutive +{ + +namespace reactiveFluid +{ + struct DerivativeOffset + { + /// index of derivative wrt pressure + static integer constexpr dP = 0; + /// index of derivative wrt temperature + static integer constexpr dT = 1; + /// index of first derivative wrt compositions + static integer constexpr dC = 2; + }; + + /// indices of pressure, temperature, and composition derivatives + template< integer NC, integer IS_THERMAL > + struct DerivativeOffsetC {}; + + template< integer NC > + struct DerivativeOffsetC< NC, 1 > + { + /// index of derivative wrt pressure + static integer constexpr dP = 0; + /// index of derivative wrt temperature + static integer constexpr dT = dP + 1; + /// index of first derivative wrt compositions + static integer constexpr dC = dP+2; + /// number of derivatives + static integer constexpr nDer = NC + 2; + }; + template< integer NC > + struct DerivativeOffsetC< NC, 0 > + { + /// index of derivative wrt pressure + static integer constexpr dP = 0; + /// index of first derivative wrt compositions + static integer constexpr dC = dP+1; + /// number of derivatives + static integer constexpr nDer = NC + 1; + }; + + #if defined( GEOS_USE_DEVICE ) + + /// Constitutive model phase property array layout + using LAYOUT_PHASE = RAJA::PERM_JKI; + /// Constitutive model phase property compositional derivative array layout + using LAYOUT_PHASE_DC = RAJA::PERM_JKLI; + + /// Constitutive model phase composition array layout + using LAYOUT_PHASE_COMP = RAJA::PERM_JKLI; + /// Constitutive model phase composition compositional derivative array layout + using LAYOUT_PHASE_COMP_DC = RAJA::PERM_JKLMI; + + /// Constitutive model fluid property array layout + using LAYOUT_FLUID = RAJA::PERM_JI; + /// Constitutive model fluid property compositional derivative array layout + using LAYOUT_FLUID_DC = RAJA::PERM_JKI; + + #else + + /// Constitutive model phase property array layout + using LAYOUT_PHASE = RAJA::PERM_IJK; + /// Constitutive model phase property compositional derivative array layout + using LAYOUT_PHASE_DC = RAJA::PERM_IJKL; + + /// Constitutive model phase composition array layout + using LAYOUT_PHASE_COMP = RAJA::PERM_IJKL; + /// Constitutive model phase composition compositional derivative array layout + using LAYOUT_PHASE_COMP_DC = RAJA::PERM_IJKLM; + + /// Constitutive model fluid property array layout + using LAYOUT_FLUID = RAJA::PERM_IJ; + /// Constitutive model fluid property compositional derivative array layout + using LAYOUT_FLUID_DC = RAJA::PERM_IJK; + + #endif + + /// Constitutive model phase property unit stride dimension + static constexpr int USD_PHASE = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_PHASE{} ); + /// Constitutive model phase property compositional derivative unit stride dimension + static constexpr int USD_PHASE_DC = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_PHASE_DC{} ); + + /// Constitutive model phase composition unit stride dimension + static constexpr int USD_PHASE_COMP = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_PHASE_COMP{} ); + /// Constitutive model phase composition compositional derivative unit stride dimension + static constexpr int USD_PHASE_COMP_DC = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_PHASE_COMP_DC{} ); + + /// Constitutive model fluid property unit stride dimension + static constexpr int USD_FLUID = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_FLUID{} ); + /// Constitutive model fluid property compositional derivative unit stride dimension + static constexpr int USD_FLUID_DC = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_FLUID_DC{} ); + +} // namespace reactivefluid +} // namespace constitutive +} // namespace geos + +#endif //GEOS_CONSTITUTIVE_SINGLEFLUID_LAYOUTS_HPP diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp new file mode 100644 index 00000000000..d0675e4123b --- /dev/null +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -0,0 +1,91 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactiveSinglePhaseFluid.cpp + */ +#include "ReactiveSinglePhaseFluid.hpp" + +namespace geos +{ + +using namespace dataRepository; + +namespace constitutive +{ + +template< typename BASE > +ReactiveSinglePhaseFluid< BASE >:: + ReactiveSinglePhaseFluid( string const & name, Group * const parent ): + BASE( name, parent ) +{ + + registerWrapper( viewKeyStruct::chemicalSystemNameString(), &m_chemicalSystemName ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "AMG smoother type. Available options are: " + "``" + EnumStrings< LinearSolverParameters::AMG::SmootherType >::concat( "|" ) + "``" ); + // For now this is being hardcoded. We will see where this should come from. + m_numPrimarySpecies = 7; + m_numSecondarySpecies = 11; + + registerField( fields::reactivefluid::primarySpeciesConcentration{}, &m_primarySpeciesConcentration ); + registerField( fields::reactivefluid::secondarySpeciesConcentration{}, &m_secondarySpeciesConcentration ); + registerField( fields::reactivefluid::primarySpeciesTotalConcentration{}, &m_primarySpeciesTotalConcentration ); +} + +template< typename BASE > +std::unique_ptr< ConstitutiveBase > ReactiveSinglePhaseFluid< BASE >:: + deliverClone( string const & name, Group * const parent ) const +{ + std::unique_ptr< ConstitutiveBase > clone = MultiFluidBase::deliverClone( name, parent ); + + ReactiveSinglePhaseFluid & newConstitutiveRelation = dynamicCast< ReactiveSinglePhaseFluid & >( *clone ); + + newConstitutiveRelation.createChemicalReactions(); + + return clone; +} + +template< typename BASE > +void ReactiveSinglePhaseFluid< BASE >::postInputInitialization() +{ + BASE::postInputInitialization(); + GEOS_THROW_IF_NE_MSG( numFluidPhases(), 1, + GEOS_FMT( "{}: invalid number of phases", getFullName() ), + InputError ); + + createChemicalReactions(); +} + +template< typename BASE > +void ReactiveSinglePhaseFluid< BASE >::resizeFields( localIndex const size, localIndex const numPts ) +{ + BASE::resizeFields( size, numPts ); + + integer const numPrimarySpecies = this->numPrimarySpecies(); + integer const numSecondarySpecies = this->numSecondarySpecies(); + + m_primarySpeciesConcentration.resize( size, numPrimarySpecies ); + m_secondarySpeciesConcentration.resize( size, numSecondarySpecies ); + m_primarySpeciesTotalConcentration.resize( size, numPrimarySpecies ); +} + +template< typename BASE > +void ReactiveSinglePhaseFluid< BASE >::createChemicalReactions() +{} + +} //namespace constitutive + +} //namespace geos diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp new file mode 100644 index 00000000000..5078897cbe2 --- /dev/null +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -0,0 +1,142 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactiveSinglePhaseFluid.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUID_REACTIVESINGLEPHASEFLUID_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUID_REACTIVESINGLEPHASEFLUID_HPP_ + +#include "common/format/EnumStrings.hpp" + +#include "constitutive/ConstitutiveBase.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp" + +#include "constitutive/HPCReact/src/reactions/bulkGeneric/Parameters.hpp" +#include "constitutive/HPCReact/src/reactions/bulkGeneric/EquilibriumReactions.hpp" +#include + +namespace geos +{ + +namespace constitutive +{ + +namespace reactivefluid +{ + +template< typename BASE > +class ReactiveSinglePhaseFluid : public BASE +{ +public: + + ReactiveSinglePhaseFluid( string const & name, + dataRepository::Group * const parent ); + + virtual std::unique_ptr< ConstitutiveBase > + deliverClone( string const & name, + dataRepository::Group * const parent ) const override; + + virtual bool isThermal() const override; + + arrayView2d< real64 const, compflow::USD_COMP > primarySpeciesConcentration() const + { return m_primarySpeciesConcentration; } + + arrayView2d< real64 const, compflow::USD_COMP > secondarySpeciesConcentration() const + { return m_secondarySpeciesConcentration; } + + arrayView2d< real64 const, compflow::USD_COMP > kineticReactionRates() const + { return m_kineticReactionRates; } + + integer numPrimarySpecies() const { return m_numPrimarySpecies; } + + integer numSecondarySpecies() const { return m_numSecondarySpecies; } + + integer numKineticReactions() const { return m_numKineticReactions; } + + enum class ChemicalSystemType : integer + { + carbonate, + ultramafic + }; + + /** + * @brief Kernel wrapper class for ReactiveSinglePhaseFluid. + */ + class KernelWrapper : public BASE::KernelWrapper + { + +public: + + using EquilibriumReactionsType = hpcReact::bulkGeneric::EquilibriumReactions< real64, integer, localIndex >; + +protected: + + arrayView2d< real64, reactiveFluid::USD_COMP > m_primarySpeciesConcentration; + + arrayView2d< real64, reactiveFluid::USD_COMP > m_secondarySpeciesConcentration; + + arrayView2d< real64, reactiveFluid::USD_COMP > m_primarySpeciesTotalConcentration; + + arrayView2d< real64, reactiveFluid::USD_COMP > m_kineticReactionRates; + + + }; + + struct viewKeyStruct : ConstitutiveBase::viewKeyStruct + {}; + +protected: + + virtual void postInputInitialization() override; + + virtual void resizeFields( localIndex const size, localIndex const numPts ) override; + + array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_primarySpeciesConcentration; + + array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_secondarySpeciesConcentration; + + array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_primarySpeciesTotalConcentration; + + array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_kineticReactionRates; + + ChemicalSystemType m_chemicalSystemType; +}; + +inline void +ReactiveSinglePhaseFluid::KernelWrapper:: + computeChemistry( real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesTotalConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & kineticReactionRates ) const +{ + auto params = hpcReact::bulkGeneric::carbonateSystem; + EquilibriumReactionsType::enforceEquilibrium_Extents( temperature, params, speciesConcentration0, speciesConcentration ); +} + +ENUM_STRINGS( ChemicalSystemType, + "carbonate", + "ultramafic" ); + +} // namespace reactivefluid + +} // namespace constitutive + +} // namespace geos + +#endif //GEOS_CONSTITUTIVE_FLUID_ReactiveSinglePhaseFluid_HPP From 4c3890b36b93f19015b0f6b9660eae7a55835a17 Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Wed, 2 Apr 2025 16:44:19 -0700 Subject: [PATCH 07/12] Remove old Reactive fluid. --- .../constitutive/CMakeLists.txt | 11 - .../reactive/ReactiveBrineFluid.cpp | 317 ------------------ .../reactive/ReactiveBrineFluid.hpp | 311 ----------------- .../reactive/ReactiveFluidSelector.hpp | 53 --- .../reactive/ReactiveMultiFluid.cpp | 97 ------ .../reactive/ReactiveMultiFluid.hpp | 245 -------------- .../reactive/ReactiveMultiFluidFields.hpp | 74 ---- .../EquilibriumReactions.cpp | 310 ----------------- .../EquilibriumReactions.hpp | 132 -------- .../chemicalReactions/KineticReactions.cpp | 205 ----------- .../chemicalReactions/KineticReactions.hpp | 124 ------- .../chemicalReactions/ReactionsBase.cpp | 152 --------- .../chemicalReactions/ReactionsBase.hpp | 170 ---------- .../reactivefluid/ReactiveFluidLayouts.hpp | 29 +- .../ReactiveSinglePhaseFluid.cpp | 32 +- .../ReactiveSinglePhaseFluid.hpp | 56 ++-- .../constitutiveDrivers/CMakeLists.txt | 2 - .../constitutiveTests/CMakeLists.txt | 16 - 18 files changed, 56 insertions(+), 2280 deletions(-) delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveBrineFluid.cpp delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveBrineFluid.hpp delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.cpp delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.hpp delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.cpp delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.hpp delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/KineticReactions.cpp delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/KineticReactions.hpp delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/ReactionsBase.cpp delete mode 100644 src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/ReactionsBase.hpp diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index c279170d2f1..1e03c4a0086 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -110,12 +110,6 @@ set( constitutive_headers fluid/multifluid/compositional/parameters/ModelParameters.hpp fluid/multifluid/compositional/CompositionalMultiphaseFluid.hpp fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp - fluid/multifluid/reactive/ReactiveBrineFluid.hpp - fluid/multifluid/reactive/ReactiveMultiFluid.hpp - fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp - fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.hpp - fluid/multifluid/reactive/chemicalReactions/KineticReactions.hpp - fluid/multifluid/reactive/chemicalReactions/ReactionsBase.hpp fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp fluid/reactivefluid/ReactiveFluidLayouts.hpp fluid/singlefluid/CompressibleSinglePhaseFluid.hpp @@ -255,11 +249,6 @@ set( constitutive_sources fluid/multifluid/compositional/parameters/ImmiscibleWaterParameters.cpp fluid/multifluid/compositional/CompositionalMultiphaseFluid.cpp fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.cpp - fluid/multifluid/reactive/ReactiveBrineFluid.cpp - fluid/multifluid/reactive/ReactiveMultiFluid.cpp - fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.cpp - fluid/multifluid/reactive/chemicalReactions/KineticReactions.cpp - fluid/multifluid/reactive/chemicalReactions/ReactionsBase.cpp fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp fluid/singlefluid/CompressibleSinglePhaseFluid.cpp fluid/singlefluid/ParticleFluid.cpp diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveBrineFluid.cpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveBrineFluid.cpp deleted file mode 100644 index 8cc14dc5850..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveBrineFluid.cpp +++ /dev/null @@ -1,317 +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 ReactiveBrineFluid.cpp - */ -#include "ReactiveBrineFluid.hpp" - -#include "constitutive/fluid/multifluid/LogLevelsInfo.hpp" -#include "constitutive/fluid/multifluid/MultiFluidFields.hpp" -#include "constitutive/fluid/multifluid/CO2Brine/functions/PVTFunctionHelpers.hpp" -#include "constitutive/ConstitutiveManager.hpp" -#include "common/Units.hpp" - -namespace geos -{ - -using namespace dataRepository; - -namespace constitutive -{ - -using namespace PVTProps; - -namespace -{ -template< typename PHASE > class - ReactiveBrineCatalogNames {}; - -template<> class - ReactiveBrineCatalogNames< PhaseModel< PVTProps::WaterDensity, PVTProps::PhillipsBrineViscosity, PVTProps::NoOpPVTFunction > > -{ -public: - static string name() { return "ReactiveBrine"; } -}; -template<> class - ReactiveBrineCatalogNames< PhaseModel< PVTProps::WaterDensity, PVTProps::PhillipsBrineViscosity, PVTProps::BrineEnthalpy > > -{ -public: - static string name() { return "ReactiveBrineThermal"; } -}; - -} // end namespace - -// provide a definition for catalogName() -template< typename PHASE > -string ReactiveBrineFluid< PHASE > ::catalogName() -{ - return ReactiveBrineCatalogNames< PHASE > ::name(); -} - -template< typename PHASE > -ReactiveBrineFluid< PHASE > :: -ReactiveBrineFluid( string const & name, Group * const parent ): - ReactiveMultiFluid( name, parent ) -{ - registerWrapper( viewKeyStruct::phasePVTParaFilesString(), &m_phasePVTParaFiles ). - setInputFlag( InputFlags::REQUIRED ). - setRestartFlags( RestartFlags::NO_WRITE ). - setDescription( "Names of the files defining the parameters of the viscosity and density models" ); - - this->registerWrapper( viewKeyStruct::writeCSVFlagString(), &m_writeCSV ). - setApplyDefaultValue( 0 ). - setInputFlag( InputFlags::OPTIONAL ). - setRestartFlags( RestartFlags::NO_WRITE ). - setDescription( "Write PVT tables into a CSV file" ); - - // if this is a thermal model, we need to make sure that the arrays will be properly displayed and saved to restart - if( isThermal() ) - { - getField< fields::multifluid::phaseEnthalpy >(). - setPlotLevel( PlotLevel::LEVEL_0 ). - setRestartFlags( RestartFlags::WRITE_AND_READ ); - - getField< fields::multifluid::phaseInternalEnergy >(). - setPlotLevel( PlotLevel::LEVEL_0 ). - setRestartFlags( RestartFlags::WRITE_AND_READ ); - } - - addLogLevel< logInfo::PVT >(); -} - -template< typename PHASE > -bool ReactiveBrineFluid< PHASE > ::isThermal() const -{ - return ( PHASE::Enthalpy::catalogName() != PVTProps::NoOpPVTFunction::catalogName() ); -} - - -template< typename PHASE > -std::unique_ptr< ConstitutiveBase > -ReactiveBrineFluid< PHASE > :: -deliverClone( string const & name, Group * const parent ) const -{ - - std::unique_ptr< ConstitutiveBase > clone = ReactiveMultiFluid::deliverClone( name, parent ); - - ReactiveBrineFluid & newConstitutiveRelation = dynamicCast< ReactiveBrineFluid & >( *clone ); - - newConstitutiveRelation.createPVTModels(); - - return clone; -} - -template< typename PHASE > -integer ReactiveBrineFluid< PHASE > ::getWaterPhaseIndex() const -{ - // There is only 1 phase - return 0; -} - - -template< typename PHASE > -void ReactiveBrineFluid< PHASE > ::postInputInitialization() -{ - ReactiveMultiFluid::postInputInitialization(); - - GEOS_THROW_IF_NE_MSG( numFluidPhases(), 1, - GEOS_FMT( "{}: invalid number of phases", getFullName() ), - InputError ); - GEOS_THROW_IF_NE_MSG( m_phasePVTParaFiles.size(), 1, - GEOS_FMT( "{}: invalid number of values in attribute '{}'", getFullName() ), - InputError ); - - createPVTModels(); -} - -template< typename PHASE > -void ReactiveBrineFluid< PHASE > ::createPVTModels() -{ - // TODO: get rid of these external files and move into XML, this is too error prone - // For now, to support the legacy input, we read all the input parameters at once in the arrays below, and then we create the models - std::vector< string_array > phase1InputParams; - phase1InputParams.resize( 3 ); - - // 1) Create the viscosity, density, enthalpy models - for( string const & filename : m_phasePVTParaFiles ) - { - std::ifstream is( filename ); - string str; - while( std::getline( is, str ) ) - { - string_array const strs = stringutilities::tokenizeBySpaces< std::vector >( str ); - - if( !strs.empty() ) - { - GEOS_THROW_IF( strs.size() < 2, - GEOS_FMT( "{}: missing PVT model in line '{}'", getFullName(), str ), - InputError ); - - if( strs[0] == "DensityFun" ) - { - if( strs[1] == PHASE::Density::catalogName() ) - { - phase1InputParams[PHASE::InputParamOrder::DENSITY] = strs; - } - } - else if( strs[0] == "ViscosityFun" ) - { - if( strs[1] == PHASE::Viscosity::catalogName() ) - { - phase1InputParams[PHASE::InputParamOrder::VISCOSITY] = strs; - } - } - else if( strs[0] == "EnthalpyFun" ) - { - if( strs[1] == PHASE::Enthalpy::catalogName() ) - { - phase1InputParams[PHASE::InputParamOrder::ENTHALPY] = strs; - } - } - else - { - GEOS_THROW( GEOS_FMT( "{}: invalid PVT function type '{}'", getFullName(), strs[0] ), InputError ); - } - } - } - is.close(); - } - - // at this point, we have read the file and we check the consistency of non-thermal models - GEOS_THROW_IF( phase1InputParams[PHASE::InputParamOrder::DENSITY].empty(), - GEOS_FMT( "{}: PVT model {} not found in input files", getFullName(), PHASE::Density::catalogName() ), - InputError ); - GEOS_THROW_IF( phase1InputParams[PHASE::InputParamOrder::VISCOSITY].empty(), - GEOS_FMT( "{}: PVT model {} not found in input files", getFullName(), PHASE::Viscosity::catalogName() ), - InputError ); - // we also detect any inconsistency arising in the enthalpy models - GEOS_THROW_IF( phase1InputParams[PHASE::InputParamOrder::ENTHALPY].empty() && - ( PHASE::Enthalpy::catalogName() != PVTProps::NoOpPVTFunction::catalogName() ), - GEOS_FMT( "{}: PVT model {} not found in input files", getFullName(), PHASE::Enthalpy::catalogName() ), - InputError ); - - bool const isClone = this->isClone(); - TableFunction::OutputOptions const pvtOutputOpts = { - !isClone && m_writeCSV,// writeCSV - !isClone && (isLogLevelActive< logInfo::PVT >( this->getLogLevel() ) && logger::internal::rank==0), // writeInLog - }; - - // then, we are ready to instantiate the phase models - m_phase = std::make_unique< PHASE >( getName() + "_phaseModel1", phase1InputParams, m_componentNames, m_componentMolarWeight, - pvtOutputOpts ); -} - -template< typename PHASE > -void ReactiveBrineFluid< PHASE >::checkTablesParameters( real64 const pressure, - real64 const temperature ) const -{ - if( !m_checkPVTTablesRanges ) - { - return; - } - - real64 const temperatureInCelsius = units::convertKToC( temperature ); - try - { - m_phase->density.checkTablesParameters( pressure, temperatureInCelsius ); - m_phase->viscosity.checkTablesParameters( pressure, temperatureInCelsius ); - m_phase->enthalpy.checkTablesParameters( pressure, temperatureInCelsius ); - } catch( SimulationError const & ex ) - { - string const errorMsg = GEOS_FMT( "Table input error (in table from {}).\n", - stringutilities::join( m_phasePVTParaFiles ) ); - throw SimulationError( ex, errorMsg ); - } -} - -template< typename PHASE > -typename ReactiveBrineFluid< PHASE > ::KernelWrapper -ReactiveBrineFluid< PHASE > ::createKernelWrapper() -{ - return KernelWrapper( *m_phase, - m_componentMolarWeight.toViewConst(), - m_useMass, - isThermal(), - m_phaseFraction.toView(), - m_phaseDensity.toView(), - m_phaseMassDensity.toView(), - m_phaseViscosity.toView(), - m_phaseEnthalpy.toView(), - m_phaseInternalEnergy.toView(), - m_phaseCompFraction.toView(), - m_totalDensity.toView(), - m_numPrimarySpecies, - *m_equilibriumReactions, - *m_kineticReactions, - m_primarySpeciesConcentration.toView(), - m_secondarySpeciesConcentration.toView(), - m_primarySpeciesTotalConcentration.toView(), - m_kineticReactionRates.toView() ); -} - -template< typename PHASE > -ReactiveBrineFluid< PHASE > ::KernelWrapper:: - KernelWrapper( PHASE const & phase, - arrayView1d< real64 const > componentMolarWeight, - bool const useMass, - bool const isThermal, - PhaseProp::ViewType phaseFraction, - PhaseProp::ViewType phaseDensity, - PhaseProp::ViewType phaseMassDensity, - PhaseProp::ViewType phaseViscosity, - PhaseProp::ViewType phaseEnthalpy, - PhaseProp::ViewType phaseInternalEnergy, - PhaseComp::ViewType phaseCompFraction, - FluidProp::ViewType totalDensity, - integer const numPrimarySpecies, - chemicalReactions::EquilibriumReactions const & equilibriumReactions, - chemicalReactions::KineticReactions const & kineticReactions, - arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesConcentration, - arrayView2d< real64, compflow::USD_COMP > const & secondarySpeciesConcentration, - arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesTotalConcentration, - arrayView2d< real64, compflow::USD_COMP > const & kineticReactionRates ) - : ReactiveMultiFluid::KernelWrapper( std::move( componentMolarWeight ), - useMass, - std::move( phaseFraction ), - std::move( phaseDensity ), - std::move( phaseMassDensity ), - std::move( phaseViscosity ), - std::move( phaseEnthalpy ), - std::move( phaseInternalEnergy ), - std::move( phaseCompFraction ), - std::move( totalDensity ), - numPrimarySpecies, - equilibriumReactions, - kineticReactions, - primarySpeciesConcentration, - secondarySpeciesConcentration, - primarySpeciesTotalConcentration, - kineticReactionRates ), - m_isThermal( isThermal ), - m_phase( phase.createKernelWrapper() ) -{} - -// explicit instantiation of the model template; unfortunately we can't use the aliases for this -template class ReactiveBrineFluid< PhaseModel< PVTProps::WaterDensity, PVTProps::PhillipsBrineViscosity, PVTProps::NoOpPVTFunction > >; -template class ReactiveBrineFluid< PhaseModel< PVTProps::WaterDensity, PVTProps::PhillipsBrineViscosity, PVTProps::BrineEnthalpy > >; - - -REGISTER_CATALOG_ENTRY( ConstitutiveBase, ReactiveBrine, string const &, Group * const ) -REGISTER_CATALOG_ENTRY( ConstitutiveBase, ReactiveBrineThermal, string const &, Group * const ) - -} //namespace constitutive - -} //namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveBrineFluid.hpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveBrineFluid.hpp deleted file mode 100644 index f1d88712b00..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveBrineFluid.hpp +++ /dev/null @@ -1,311 +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 ReactiveBrineFluid.hpp - */ - -#ifndef GEOS_CONSTITUTIVE_FLUID_REACTIVEBRINEFLUID_HPP_ -#define GEOS_CONSTITUTIVE_FLUID_REACTIVEBRINEFLUID_HPP_ - -#include "common/format/EnumStrings.hpp" -#include "constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.hpp" -#include "constitutive/fluid/multifluid/MultiFluidUtils.hpp" -#include "constitutive/fluid/multifluid/CO2Brine/PhaseModel.hpp" -#include "constitutive/fluid/multifluid/CO2Brine/functions/BrineEnthalpy.hpp" -#include "constitutive/fluid/multifluid/CO2Brine/functions/NoOpPVTFunction.hpp" -#include "constitutive/fluid/multifluid/CO2Brine/functions/WaterDensity.hpp" -#include "constitutive/fluid/multifluid/CO2Brine/functions/PhillipsBrineViscosity.hpp" -#include "constitutive/fluid/multifluid/CO2Brine/functions/PureWaterProperties.hpp" -#include "common/Units.hpp" - - - -#include - -namespace geos -{ - -namespace constitutive -{ - -template< typename PHASE > -class ReactiveBrineFluid : public ReactiveMultiFluid -{ -public: - - using exec_policy = parallelDevicePolicy<>; - - ReactiveBrineFluid( string const & name, - Group * const parent ); - - virtual std::unique_ptr< ConstitutiveBase > - deliverClone( string const & name, - Group * const parent ) const override; - - static string catalogName(); - - virtual string getCatalogName() const override { return catalogName(); } - - virtual bool isThermal() const override final; - - /** - * @copydoc MultiFluidBase::checkTablesParameters( real64 pressure, real64 temperature ) - */ - void checkTablesParameters( real64 pressure, real64 temperature ) const override final; - - /** - * @brief Kernel wrapper class for ReactiveBrineFluid. - */ - class KernelWrapper final : public ReactiveMultiFluid::KernelWrapper - { -public: - GEOS_HOST_DEVICE - virtual void compute( real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition, - PhaseProp::SliceType const phaseFraction, - PhaseProp::SliceType const phaseDensity, - PhaseProp::SliceType const phaseMassDensity, - PhaseProp::SliceType const phaseViscosity, - PhaseProp::SliceType const phaseEnthalpy, - PhaseProp::SliceType const phaseInternalEnergy, - PhaseComp::SliceType const phaseCompFraction, - FluidProp::SliceType const totalDensity ) const override; - - GEOS_HOST_DEVICE - virtual void update( localIndex const k, - localIndex const q, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition ) const override; - - virtual void updateChemistry( localIndex const k, - localIndex const q, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition ) const override; - -private: - - friend class ReactiveBrineFluid; - - KernelWrapper( PHASE const & phase, - arrayView1d< real64 const > componentMolarWeight, - bool const useMass, - bool const isThermal, - PhaseProp::ViewType phaseFraction, - PhaseProp::ViewType phaseDensity, - PhaseProp::ViewType phaseMassDensity, - PhaseProp::ViewType phaseViscosity, - PhaseProp::ViewType phaseEnthalpy, - PhaseProp::ViewType phaseInternalEnergy, - PhaseComp::ViewType phaseCompFraction, - FluidProp::ViewType totalDensity, - integer const numPrimarySpecies, - chemicalReactions::EquilibriumReactions const & equilibriumReactions, - chemicalReactions::KineticReactions const & kineticReactions, - arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesConcentration, - arrayView2d< real64, compflow::USD_COMP > const & secondarySpeciesConcentration, - arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesTotalConcentration, - arrayView2d< real64, compflow::USD_COMP > const & kineticReactionRates ); - - - /// Flag to specify whether the model is thermal or not - bool m_isThermal; - - /// Brine constitutive kernel wrappers - typename PHASE::KernelWrapper m_phase; - - }; - - virtual integer getWaterPhaseIndex() const override final; - - /** - * @brief Names of the submodels for input - */ - enum class SubModelInputNames : integer - { - DENSITY, ///< the keyword for the density model - VISCOSITY, ///< the keyword for the viscosity model - ENTHALPY ///< the keyword for the enthalpy model - }; - - /** - * @brief Create an update kernel wrapper. - * @return the wrapper - */ - KernelWrapper createKernelWrapper(); - - struct viewKeyStruct : ReactiveMultiFluid::viewKeyStruct - { - static constexpr char const * phasePVTParaFilesString() { return "phasePVTParaFiles"; } - static constexpr char const * writeCSVFlagString() { return "writeCSV"; } - }; - -protected: - - virtual void postInputInitialization() override; - -private: - - /** - * @brief Create a PVT Model and output them - */ - void createPVTModels(); - - /// Names of the files defining the viscosity and density models - path_array m_phasePVTParaFiles; - - /// Output csv file containing informations about PVT - integer m_writeCSV; - - /// Brine constitutive models - std::unique_ptr< PHASE > m_phase; - -}; - -// these aliases are useful in constitutive dispatch -using ReactiveBrine = - ReactiveBrineFluid< PhaseModel< PVTProps::WaterDensity, PVTProps::PhillipsBrineViscosity, PVTProps::NoOpPVTFunction > >; -using ReactiveBrineThermal = - ReactiveBrineFluid< PhaseModel< PVTProps::WaterDensity, PVTProps::PhillipsBrineViscosity, PVTProps::BrineEnthalpy > >; - -template< typename PHASE > -GEOS_HOST_DEVICE -inline void -ReactiveBrineFluid< PHASE >::KernelWrapper:: - compute( real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition, - PhaseProp::SliceType const phaseFraction, - PhaseProp::SliceType const phaseDensity, - PhaseProp::SliceType const phaseMassDensity, - PhaseProp::SliceType const phaseViscosity, - PhaseProp::SliceType const phaseEnthalpy, - PhaseProp::SliceType const phaseInternalEnergy, - PhaseComp::SliceType const phaseCompFraction, - FluidProp::SliceType const totalDensity ) const -{ - integer constexpr numComp = chemicalReactions::ReactionsBase::maxNumPrimarySpecies; - - // 1. We perform a sort of single phase flash - stackArray1d< real64, numComp > compMoleFrac( composition.size() ); - - phaseFraction.value[0] = 1.0; // it's a single phase system - for( integer ic = 0; ic < composition.size(); ++ic ) - { - compMoleFrac[ic] = composition[ic]; - phaseCompFraction.value[0][ic] = composition[ic]; - } - - real64 const temperatureInCelsius = units::convertKToC( temperature ); - - // 2. Compute phase densities and phase viscosities - m_phase.density.compute( pressure, - temperatureInCelsius, - phaseCompFraction.value[0].toSliceConst(), phaseCompFraction.derivs[0].toSliceConst(), - phaseDensity.value[0], phaseDensity.derivs[0], - m_useMass ); - - m_phase.viscosity.compute( pressure, - temperatureInCelsius, - phaseCompFraction.value[0].toSliceConst(), phaseCompFraction.derivs[0].toSliceConst(), - phaseViscosity.value[0], phaseViscosity.derivs[0], - m_useMass ); - - - // for now, we have to compute the phase mass density here - m_phase.density.compute( pressure, - temperatureInCelsius, - phaseCompFraction.value[0].toSliceConst(), phaseCompFraction.derivs[0].toSliceConst(), - phaseMassDensity.value[0], phaseMassDensity.derivs[0], - true ); - - // 3. Compute enthalpy and internal energy - if( m_isThermal ) - { - m_phase.enthalpy.compute( pressure, - temperatureInCelsius, - phaseCompFraction.value[0].toSliceConst(), phaseCompFraction.derivs[0].toSliceConst(), - phaseEnthalpy.value[0], phaseEnthalpy.derivs[0], - m_useMass ); - - computeInternalEnergy( pressure, - phaseFraction, - phaseMassDensity, - phaseEnthalpy, - phaseInternalEnergy ); - } - - // 6. Compute total fluid mass/molar density and derivatives - computeTotalDensity( phaseFraction, - phaseDensity, - totalDensity ); -} - -template< typename PHASE > -GEOS_HOST_DEVICE inline void -ReactiveBrineFluid< PHASE >::KernelWrapper:: - update( localIndex const k, - localIndex const q, - real64 const pressure, - real64 const temperature, - arraySlice1d< geos::real64 const, compflow::USD_COMP - 1 > const & composition ) const -{ - compute( pressure, - temperature, - composition, - m_phaseFraction( k, q ), - m_phaseDensity( k, q ), - m_phaseMassDensity( k, q ), - m_phaseViscosity( k, q ), - m_phaseEnthalpy( k, q ), - m_phaseInternalEnergy( k, q ), - m_phaseCompFraction( k, q ), - m_totalDensity( k, q ) ); -} - -template< typename PHASE > -inline void -ReactiveBrineFluid< PHASE >::KernelWrapper:: - updateChemistry( localIndex const k, - localIndex const q, - real64 const pressure, - real64 const temperature, - arraySlice1d< geos::real64 const, compflow::USD_COMP - 1 > const & composition ) const - -{ - real64 const totalMolecularWeight = PVTProps::PureWaterProperties::MOLECULAR_WEIGHT; - - convertMoleFractionToMolarity( m_totalDensity( k, q ).value, - totalMolecularWeight, - composition, - m_primarySpeciesTotalConcentration[k] ); - - computeChemistry( pressure, - temperature, - m_primarySpeciesTotalConcentration[k], - m_primarySpeciesConcentration[k], - m_secondarySpeciesConcentration[k], - m_kineticReactionRates[k] ); -} - - -} // namespace constitutive - -} // namespace geos - -#endif //GEOS_CONSTITUTIVE_FLUID_REACTIVEBRINEFLUID_HPP_ diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp deleted file mode 100644 index 03439e9629b..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp +++ /dev/null @@ -1,53 +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 ReactiveFluidSelector.hpp - */ -#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_REACTIVE_REACTIVEFLUIDSELECTOR_HPP_ -#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_REACTIVE_REACTIVEFLUIDSELECTOR_HPP_ - -#include "constitutive/ConstitutivePassThruHandler.hpp" -#include "constitutive/fluid/multifluid/reactive/ReactiveBrineFluid.hpp" - -#include "common/GeosxConfig.hpp" - -namespace geos -{ - -namespace constitutive -{ - -template< typename LAMBDA > -void constitutiveUpdatePassThru( ReactiveMultiFluid const & fluid, - LAMBDA && lambda ) -{ - ConstitutivePassThruHandler< ReactiveBrine, - ReactiveBrineThermal >::execute( fluid, std::forward< LAMBDA >( lambda ) ); -} - -template< typename LAMBDA > -void constitutiveUpdatePassThru( ReactiveMultiFluid & fluid, - LAMBDA && lambda ) -{ - ConstitutivePassThruHandler< ReactiveBrine, - ReactiveBrineThermal >::execute( fluid, std::forward< LAMBDA >( lambda ) ); -} - -} // namespace constitutive - -} // namespace geos - -#endif //GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUIDSELECTOR_HPP_ diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.cpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.cpp deleted file mode 100644 index 09ac848a16a..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.cpp +++ /dev/null @@ -1,97 +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 ReactiveMultiFluid.cpp - */ -#include "ReactiveMultiFluid.hpp" -#include "ReactiveMultiFluidFields.hpp" - - -namespace geos -{ - -using namespace dataRepository; - -namespace constitutive -{ - -ReactiveMultiFluid:: - ReactiveMultiFluid( string const & name, Group * const parent ): - MultiFluidBase( name, parent ) -{ - // For now this is being hardcoded. We will see where this should come from. - m_numPrimarySpecies = 7; - m_numSecondarySpecies = 11; - m_numKineticReactions = 2; - - registerField( fields::reactivefluid::primarySpeciesConcentration{}, &m_primarySpeciesConcentration ); - registerField( fields::reactivefluid::secondarySpeciesConcentration{}, &m_secondarySpeciesConcentration ); - registerField( fields::reactivefluid::primarySpeciesTotalConcentration{}, &m_primarySpeciesTotalConcentration ); - registerField( fields::reactivefluid::kineticReactionRates{}, &m_kineticReactionRates ); -} - -bool ReactiveMultiFluid::isThermal() const -{ - return true; -} - -std::unique_ptr< ConstitutiveBase > ReactiveMultiFluid:: - deliverClone( string const & name, Group * const parent ) const -{ - std::unique_ptr< ConstitutiveBase > clone = MultiFluidBase::deliverClone( name, parent ); - - ReactiveMultiFluid & newConstitutiveRelation = dynamicCast< ReactiveMultiFluid & >( *clone ); - - newConstitutiveRelation.createChemicalReactions(); - - return clone; -} - -void ReactiveMultiFluid::postInputInitialization() -{ - MultiFluidBase::postInputInitialization(); - - GEOS_THROW_IF_NE_MSG( numFluidPhases(), 1, - GEOS_FMT( "{}: invalid number of phases", getFullName() ), - InputError ); - - createChemicalReactions(); -} - -void ReactiveMultiFluid::resizeFields( localIndex const size, localIndex const numPts ) -{ - MultiFluidBase::resizeFields( size, numPts ); - - integer const numPrimarySpecies = this->numPrimarySpecies(); - integer const numSecondarySpecies = this->numSecondarySpecies(); - integer const numKineticReactions = this->numKineticReactions(); - - m_primarySpeciesConcentration.resize( size, numPrimarySpecies ); - m_secondarySpeciesConcentration.resize( size, numSecondarySpecies ); - m_primarySpeciesTotalConcentration.resize( size, numPrimarySpecies ); - m_kineticReactionRates.resize( size, numKineticReactions ); -} - -void ReactiveMultiFluid::createChemicalReactions() -{ - // instantiate reactions objects - m_equilibriumReactions = std::make_unique< chemicalReactions::EquilibriumReactions >( getName() + "_equilibriumReactions", m_numPrimarySpecies, m_numSecondarySpecies ); - m_kineticReactions = std::make_unique< chemicalReactions::KineticReactions >( getName() + "_kineticReactions", m_numPrimarySpecies, m_numSecondarySpecies, m_numKineticReactions ); -} - -} //namespace constitutive - -} //namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.hpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.hpp deleted file mode 100644 index 71ebd796571..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluid.hpp +++ /dev/null @@ -1,245 +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 ReactiveMultiFluid.hpp - */ - -#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_REACTIVE_REACTIVEMULTIFLUID_HPP_ -#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_REACTIVE_REACTIVEMULTIFLUID_HPP_ - - -#include "common/format/EnumStrings.hpp" -#include "constitutive/fluid/multifluid/MultiFluidBase.hpp" -#include "constitutive/fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.hpp" -#include "constitutive/fluid/multifluid/reactive/chemicalReactions/KineticReactions.hpp" - -#include - -namespace geos -{ - -namespace constitutive -{ - -class ReactiveMultiFluid : public MultiFluidBase -{ -public: - - using exec_policy = serialPolicy; - - ReactiveMultiFluid( string const & name, - Group * const parent ); - - virtual std::unique_ptr< ConstitutiveBase > - deliverClone( string const & name, - Group * const parent ) const override; - - virtual bool isThermal() const override; - - arrayView2d< real64 const, compflow::USD_COMP > primarySpeciesConcentration() const - { return m_primarySpeciesConcentration; } - - arrayView2d< real64 const, compflow::USD_COMP > secondarySpeciesConcentration() const - { return m_secondarySpeciesConcentration; } - - arrayView2d< real64 const, compflow::USD_COMP > kineticReactionRates() const - { return m_kineticReactionRates; } - - integer numPrimarySpecies() const { return m_numPrimarySpecies; } - - integer numSecondarySpecies() const { return m_numSecondarySpecies; } - - integer numKineticReactions() const { return m_numKineticReactions; } - - /** - * @brief Kernel wrapper class for ReactiveMultiFluid. - */ - class KernelWrapper : public MultiFluidBase::KernelWrapper - { - -public: - - void computeChemistry( real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesTotalConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & kineticReactionRates ) const; - - virtual void updateChemistry( localIndex const k, - localIndex const q, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & composition ) const = 0; - - /** - * @brief Construct a new Kernel Wrapper object - * - * @param componentMolarWeight - * @param useMass - * @param isThermal - * @param phaseFraction - * @param phaseDensity - * @param phaseMassDensity - * @param phaseViscosity - * @param phaseEnthalpy - * @param phaseInternalEnergy - * @param phaseCompFraction - * @param totalDensity - * @param numPrimarySpecies - * @param equilibriumReactions - * @param kineticReactions - * @param primarySpeciesConcentration - * @param secondarySpeciesConcentration - * @param primarySpeciesTotalConcentration - * @param kineticReactionRates - */ - KernelWrapper( arrayView1d< real64 const > componentMolarWeight, - bool const useMass, - PhaseProp::ViewType phaseFraction, - PhaseProp::ViewType phaseDensity, - PhaseProp::ViewType phaseMassDensity, - PhaseProp::ViewType phaseViscosity, - PhaseProp::ViewType phaseEnthalpy, - PhaseProp::ViewType phaseInternalEnergy, - PhaseComp::ViewType phaseCompFraction, - FluidProp::ViewType totalDensity, - integer const numPrimarySpecies, - chemicalReactions::EquilibriumReactions const & equilibriumReactions, - chemicalReactions::KineticReactions const & kineticReactions, - arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesConcentration, - arrayView2d< real64, compflow::USD_COMP > const & secondarySpeciesConcentration, - arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesTotalConcentration, - arrayView2d< real64, compflow::USD_COMP > const & kineticReactionRates ): - MultiFluidBase::KernelWrapper( std::move( componentMolarWeight ), - useMass, - std::move( phaseFraction ), - std::move( phaseDensity ), - std::move( phaseMassDensity ), - std::move( phaseViscosity ), - std::move( phaseEnthalpy ), - std::move( phaseInternalEnergy ), - std::move( phaseCompFraction ), - std::move( totalDensity ) ), - m_numPrimarySpecies( numPrimarySpecies ), - m_equilibriumReactions( equilibriumReactions.createKernelWrapper() ), - m_kineticReactions( kineticReactions.createKernelWrapper() ), - m_primarySpeciesConcentration( primarySpeciesConcentration ), - m_secondarySpeciesConcentration( secondarySpeciesConcentration ), - m_primarySpeciesTotalConcentration( primarySpeciesTotalConcentration ), - m_kineticReactionRates( kineticReactionRates ) - {} - -protected: - - void convertMoleFractionToMolarity( real64 const totalDensity, - real64 const totalMolecularWeight, - arraySlice1d< geos::real64 const, compflow::USD_COMP - 1 > const & composition, - arraySlice1d< geos::real64, compflow::USD_COMP - 1 > const & primarySpeciesTotalConcentration ) const; - - friend class ReactiveMultiFluid; - /// Reaction related terms - integer m_numPrimarySpecies; - - chemicalReactions::EquilibriumReactions::KernelWrapper m_equilibriumReactions; - - chemicalReactions::KineticReactions::KernelWrapper m_kineticReactions; - - arrayView2d< real64, compflow::USD_COMP > m_primarySpeciesConcentration; - - arrayView2d< real64, compflow::USD_COMP > m_secondarySpeciesConcentration; - - arrayView2d< real64, compflow::USD_COMP > m_primarySpeciesTotalConcentration; - - arrayView2d< real64, compflow::USD_COMP > m_kineticReactionRates; - }; - - struct viewKeyStruct : ConstitutiveBase::viewKeyStruct - {}; - -protected: - - virtual void postInputInitialization() override; - - void createChemicalReactions(); - - virtual void resizeFields( localIndex const size, localIndex const numPts ) override; - - /// Reaction related terms - integer m_numPrimarySpecies; - - integer m_numSecondarySpecies; - - integer m_numKineticReactions; - - std::unique_ptr< chemicalReactions::EquilibriumReactions > m_equilibriumReactions; - - std::unique_ptr< chemicalReactions::KineticReactions > m_kineticReactions; - - array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_primarySpeciesConcentration; - - array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_secondarySpeciesConcentration; - - array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_primarySpeciesTotalConcentration; - - array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_kineticReactionRates; -}; - -inline void -ReactiveMultiFluid::KernelWrapper:: - computeChemistry( real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesTotalConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & kineticReactionRates ) const -{ - GEOS_UNUSED_VAR( pressure ); - - // 2. solve for equilibrium - m_equilibriumReactions.updateConcentrations( temperature, - primarySpeciesTotalConcentration, - primarySpeciesConcentration, - secondarySpeciesConcentration ); - - // 3. compute kinetic reaction rates - m_kineticReactions.computeReactionRates( temperature, - primarySpeciesConcentration, - secondarySpeciesConcentration, - kineticReactionRates ); -} - - -inline void -ReactiveMultiFluid::KernelWrapper:: - convertMoleFractionToMolarity( real64 const totalDensity, - real64 const totalMolecularWeight, - arraySlice1d< geos::real64 const, compflow::USD_COMP - 1 > const & composition, - arraySlice1d< geos::real64, compflow::USD_COMP - 1 > const & primarySpeciesTotalConcentration ) const -{ - // 1. Convert from mole fraction to molarity ( mol/L ) - real64 const conversionFactor = totalDensity / totalMolecularWeight * 1e-3; //conversion to L instead of cubic meters - for( int i=0; i < m_numPrimarySpecies; i++ ) - { - primarySpeciesTotalConcentration[i] = composition[i] * conversionFactor; - } -} - -} // namespace constitutive - -} // namespace geos - -#endif //GEOS_CONSTITUTIVE_FLUID_REACTIVEMULTIFLUID_HPP diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp deleted file mode 100644 index d3a3a77f967..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp +++ /dev/null @@ -1,74 +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 ReactiveMultiFluidFields.hpp - */ - -#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_REACTIVE_MULTIFLUIDFIELDS_HPP_ -#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_REACTIVE_MULTIFLUIDFIELDS_HPP_ - -#include "constitutive/fluid/multifluid/Layouts.hpp" -#include "mesh/MeshFields.hpp" - -namespace geos -{ - -namespace fields -{ - -namespace reactivefluid -{ - -using array2dLayoutComp = array2d< real64, compflow::LAYOUT_COMP >; - -DECLARE_FIELD( primarySpeciesConcentration, - "primarySpeciesConcentration", - array2dLayoutComp, - 0, - LEVEL_0, - WRITE_AND_READ, - "primarySpeciesConcentration" ); - -DECLARE_FIELD( primarySpeciesTotalConcentration, - "primarySpeciesTotalConcentration", - array2dLayoutComp, - 0, - LEVEL_0, - WRITE_AND_READ, - "primarySpeciesTotalConcentration" ); - -DECLARE_FIELD( secondarySpeciesConcentration, - "secondarySpeciesConcentration", - array2dLayoutComp, - 0, - LEVEL_0, - WRITE_AND_READ, - "secondarySpeciesConcentration" ); - -DECLARE_FIELD( kineticReactionRates, - "kineticReactionRates", - array2dLayoutComp, - 0, - LEVEL_0, - WRITE_AND_READ, - "kineticReactionRates" ); -} - -} - -} - -#endif // GEOS_CONSTITUTIVE_FLUID_MULTIFLUIDFIELDS_HPP_ diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.cpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.cpp deleted file mode 100644 index 8ae3e0c8ee2..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.cpp +++ /dev/null @@ -1,310 +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 EquilibriumReactions.cpp - */ - -#include "EquilibriumReactions.hpp" - -#include "functions/FunctionManager.hpp" -#include "denseLinearAlgebra/interfaces/blaslapack/BlasLapackLA.hpp" - -namespace geos -{ - -using namespace stringutilities; - -namespace constitutive -{ - -namespace chemicalReactions -{ - -EquilibriumReactions::EquilibriumReactions( string const & name, integer const numPrimarySpecies, integer const numSecSpecies ): - ReactionsBase( name, numPrimarySpecies, numSecSpecies ) -{ - // Here we should either read the database or the input values. - - // Hardcoding values for now - - - - // Stochiometric Matrix - // First index: 0 = OH-, 1 = CO2, 2 = CO3-2, 3 = H2CO3, 4 = CaHCO3+, 5 = CaCO3, 6 = CaSO4, 7 = CaCl+, 8 = CaCl2, 9 = MgSO4, 10 = NaSO4- - // Second index: 0 = H+, 1 = HCO3-, 2 = Ca+2, 3 = SO4-2, 4 = Cl-, 5 = Mg+2, 6 = Na+1 - m_stoichMatrix.resize( m_numSecondarySpecies, m_numPrimarySpecies ); - m_stoichMatrix[0][0] = -1; - m_stoichMatrix[1][0] = 1; - m_stoichMatrix[1][1] = 1; - m_stoichMatrix[2][0] = -1; - m_stoichMatrix[2][1] = 1; - m_stoichMatrix[3][0] = 1; - m_stoichMatrix[3][1] = 1; - m_stoichMatrix[4][1] = 1; - m_stoichMatrix[4][2] = 1; - m_stoichMatrix[5][0] = -1; - m_stoichMatrix[5][1] = 1; - m_stoichMatrix[5][2] = 1; - m_stoichMatrix[6][2] = 1; - m_stoichMatrix[6][3] = 1; - m_stoichMatrix[7][2] = 1; - m_stoichMatrix[7][4] = 1; - m_stoichMatrix[8][2] = 1; - m_stoichMatrix[8][4] = 2; - m_stoichMatrix[9][5] = 1; - m_stoichMatrix[9][3] = 1; - m_stoichMatrix[10][6] = 1; - m_stoichMatrix[10][3] = 1; - - // Equilibrium Constant - m_log10EqConst.resize( m_numSecondarySpecies ); - m_log10EqConst[0] = 13.99; - m_log10EqConst[1] = -6.36; - m_log10EqConst[2] = 10.33; - m_log10EqConst[3] = -3.77; - m_log10EqConst[4] = -1.09; - m_log10EqConst[5] = 7.07; - m_log10EqConst[6] = -2.16; - m_log10EqConst[7] = 0.67; - m_log10EqConst[8] = 0.60; - m_log10EqConst[9] = -2.43; - m_log10EqConst[10] = -0.82; -} - -EquilibriumReactions::KernelWrapper EquilibriumReactions::createKernelWrapper() const -{ - return KernelWrapper( m_numPrimarySpecies, - m_numSecondarySpecies, - m_log10EqConst, - m_stoichMatrix, - m_chargePrimary, - m_chargeSec, - m_ionSizePrimary, - m_ionSizeSec, - m_DebyeHuckelA, - m_DebyeHuckelB, - m_WATEQBDot ); -} - -void EquilibriumReactions::KernelWrapper::assembleEquilibriumReactionSystem( real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesTotalConcentration, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - arraySlice2d< real64 > const & matrix, - arraySlice1d< real64 > const & rhs ) const -{ - - stackArray1d< real64, ReactionsBase::maxNumPrimarySpecies > log10PrimaryActCoeff( m_numPrimarySpecies ); - stackArray1d< real64, ReactionsBase::maxNumSecondarySpecies > log10SecActCoeff( m_numSecondarySpecies ); - stackArray2d< real64, ReactionsBase::maxNumSecondarySpecies * ReactionsBase::maxNumPrimarySpecies > dLog10SecConc_dLog10PrimaryConc( m_numSecondarySpecies, m_numPrimarySpecies ); - stackArray1d< real64, ReactionsBase::maxNumPrimarySpecies > totalConcentration( m_numPrimarySpecies ); - stackArray2d< real64, ReactionsBase::maxNumPrimarySpecies * ReactionsBase::maxNumPrimarySpecies > dTotalConc_dLog10PrimaryConc( m_numPrimarySpecies, m_numPrimarySpecies ); - - real64 ionicStrength = 0.0; - stackArray1d< real64, ReactionsBase::maxNumPrimarySpecies > dIonicStrength_dPrimaryConcentration( m_numPrimarySpecies ); - stackArray1d< real64, ReactionsBase::maxNumPrimarySpecies > dLog10PrimaryActCoeff_dIonicStrength( m_numPrimarySpecies ); - stackArray1d< real64, ReactionsBase::maxNumSecondarySpecies > dLog10SecActCoeff_dIonicStrength( m_numSecondarySpecies ); - - /// activity coefficients - computeIonicStrength( primarySpeciesConcentration, - secondarySpeciesConcentration, - ionicStrength ); - - computeLog10ActCoefBDotModel( temperature, - ionicStrength, - log10PrimaryActCoeff, - dLog10PrimaryActCoeff_dIonicStrength, - log10SecActCoeff, - dLog10SecActCoeff_dIonicStrength ); - - computeSeondarySpeciesConcAndDerivative( temperature, - log10PrimaryActCoeff, - dLog10PrimaryActCoeff_dIonicStrength, - log10SecActCoeff, - dLog10SecActCoeff_dIonicStrength, - primarySpeciesConcentration, - secondarySpeciesConcentration, - dLog10SecConc_dLog10PrimaryConc ); - - computeTotalConcAndDerivative( temperature, - primarySpeciesConcentration, - secondarySpeciesConcentration, - dLog10SecConc_dLog10PrimaryConc, - totalConcentration, - dTotalConc_dLog10PrimaryConc ); - - for( int i=0; i const & primarySpeciesTotalConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration ) const - -{ - stackArray2d< real64, ReactionsBase::maxNumPrimarySpecies * ReactionsBase::maxNumPrimarySpecies > matrix( m_numPrimarySpecies, m_numPrimarySpecies ); - stackArray1d< real64, ReactionsBase::maxNumPrimarySpecies > rhs( m_numPrimarySpecies ); - stackArray1d< real64, ReactionsBase::maxNumPrimarySpecies > solution( m_numPrimarySpecies ); - - setInitialGuess( primarySpeciesTotalConcentration, primarySpeciesConcentration ); - - bool converged = false; - for( int iteration = 0; iteration < m_maxNumIterations; iteration++ ) - { - - for( int i = 0; i< m_numPrimarySpecies; i++ ) - { - rhs[i] = 0.0; - solution[i] = 0.0; - for( int j = 0; j< m_numPrimarySpecies; j++ ) - { - matrix( i, j ) = 0.0; - } - } - - assembleEquilibriumReactionSystem( temperature, - primarySpeciesTotalConcentration, - primarySpeciesConcentration, - secondarySpeciesConcentration, - matrix, - rhs ); - - real64 const residualNorm = BlasLapackLA::vectorNorm2( rhs.toSliceConst() ); - - if( residualNorm < m_newtonTol && iteration >= 1 ) - { - converged = true; - break; - } - - BlasLapackLA::solveLinearSystem( matrix, rhs, solution ); - - updatePrimarySpeciesConcentrations( solution, primarySpeciesConcentration ); - } - GEOS_ERROR_IF( !converged, "Equilibrium reactions did not converge." ); -} - -// function to compute the derivative of the concentration of secondary species with respect to the concentration of the primary species. -void EquilibriumReactions::KernelWrapper::computeSeondarySpeciesConcAndDerivative( real64 const temperature, - arraySlice1d< real64 const > const & log10PrimaryActCoeff, - arraySlice1d< real64 const > const & dLog10PrimaryActCoeff_dIonicStrength, - arraySlice1d< real64 const > const & log10SecActCoeff, - arraySlice1d< real64 const > const & dLog10SecActCoeff_dIonicStrength, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConectration, - arraySlice2d< real64 > const & dLog10SecConc_dLog10PrimaryConc ) const -{ - GEOS_UNUSED_VAR( temperature ); - - // Compute d(concentration of dependent species)/d(concentration of basis species) - for( int iSec = 0; iSec < m_numSecondarySpecies; iSec++ ) - { - real64 log10SecConc = -m_log10EqConst[iSec] - log10SecActCoeff[iSec]; - - for( int jPri = 0; jPri < m_numPrimarySpecies; jPri++ ) - { - real64 const dIonicStrength_dPrimaryConc = log( 10 ) * 0.5 * m_chargePrimary[jPri] * m_chargePrimary[jPri]; - - log10SecConc += m_stoichMatrix[iSec][jPri] * ( log10( primarySpeciesConcentration[jPri] ) + log10PrimaryActCoeff[jPri] ); - dLog10SecConc_dLog10PrimaryConc[iSec][jPri] += m_stoichMatrix[iSec][jPri] - dLog10SecActCoeff_dIonicStrength[iSec] * primarySpeciesConcentration[jPri] * - dIonicStrength_dPrimaryConc; - for( int kDerivative = 0; kDerivative < m_numPrimarySpecies; kDerivative++ ) - { - // add contribution to the derivtive from all primary activity coefficients - dLog10SecConc_dLog10PrimaryConc[iSec][jPri] += m_stoichMatrix[iSec][kDerivative] * dLog10PrimaryActCoeff_dIonicStrength[kDerivative] * primarySpeciesConcentration[jPri] * - dIonicStrength_dPrimaryConc; - } - - } - secondarySpeciesConectration[iSec] = pow( 10, log10SecConc ); - } - -} - -void EquilibriumReactions::KernelWrapper::computeTotalConcAndDerivative( real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & secondarySpeciesConectration, - arraySlice2d< real64 const > const & dLog10SecConc_dLog10PrimaryConc, - arraySlice1d< real64 > const & totalConc, - arraySlice2d< real64 > const & dTotalConc_dLog10PrimaryConc ) const - - -{ - GEOS_UNUSED_VAR( temperature ); - - // This function computes the total concentration and its derivative with respect to log10(basis species concentrations). - for( int iPri = 0; iPri < m_numPrimarySpecies; iPri++ ) - { - totalConc[iPri] = primarySpeciesConcentration[iPri]; - // d(total concentration)/d(log10(concentration)) - dTotalConc_dLog10PrimaryConc[iPri][iPri] = log( 10.0 ) * primarySpeciesConcentration[iPri]; - // contribution from all dependent species - for( int jSec = 0; jSec < m_numSecondarySpecies; jSec++ ) - { - totalConc[iPri] += m_stoichMatrix[jSec][iPri] * secondarySpeciesConectration[jSec]; - for( int kDerivative = 0; kDerivative < m_numPrimarySpecies; kDerivative++ ) - { - // add contribution to the derivtive from dependent species via the chain rule - dTotalConc_dLog10PrimaryConc[iPri][kDerivative] += m_stoichMatrix[jSec][iPri] * log( 10.0 ) * - secondarySpeciesConectration[jSec] * dLog10SecConc_dLog10PrimaryConc[jSec][kDerivative]; - } - } - } -} - -void EquilibriumReactions::KernelWrapper:: - updatePrimarySpeciesConcentrations( arraySlice1d< real64 const > const solution, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration ) const -{ - for( integer i = 0; i < m_numPrimarySpecies; i++ ) - { - primarySpeciesConcentration[i] *= pow( 10, solution[i] ); - } -} - -void EquilibriumReactions::KernelWrapper::setInitialGuess( arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesTotalConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration ) const -{ - for( integer i = 0; i < m_numPrimarySpecies; i++ ) - { - primarySpeciesConcentration[i] = primarySpeciesTotalConcentration[i]; - } - real64 const hPlusConcentration = 2*primarySpeciesConcentration[2]-2*primarySpeciesConcentration[3]-primarySpeciesConcentration[4]+2*primarySpeciesConcentration[5]+primarySpeciesConcentration[6]; - if( hPlusConcentration < 0 ) - { - primarySpeciesConcentration[0] = -hPlusConcentration; - } - else - { - primarySpeciesConcentration[0] = 1e-7; - } - -} - - -} // end namespace chemicalReactions - -} // namespace constitutive - -} // end namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.hpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.hpp deleted file mode 100644 index e3908d4df7d..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.hpp +++ /dev/null @@ -1,132 +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 EquilibriumReactions.hpp - */ - -#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_REACTIVE_CHEMICALREACTIONS_EQUILIBRIUMREACTIONS_HPP_ -#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_REACTIVE_CHEMICALREACTIONS_EQUILIBRIUMREACTIONS_HPP_ - -#include "ReactionsBase.hpp" - -#include "constitutive/fluid/multifluid/Layouts.hpp" -#include "constitutive/fluid/multifluid/MultiFluidConstants.hpp" - -namespace geos -{ - -namespace constitutive -{ - -namespace chemicalReactions -{ - -class EquilibriumReactions : public ReactionsBase -{ -public: - - EquilibriumReactions( string const & name, integer const numPrimarySpecies, integer const numSecSpecies ); - - class KernelWrapper final : public ReactionsBase::KernelWrapper - { -public: - - KernelWrapper( integer const numPrimarySpecies, - integer const numSecondarySpecies, - arrayView1d< real64 > const & log10EqConst, - arrayView2d< real64 > const & stoichMatrix, - arrayView1d< integer > const & chargePrimary, - arrayView1d< integer > const & chargeSec, - arrayView1d< real64 > const & ionSizePrimary, - arrayView1d< real64 > const & ionSizeSec, - real64 const DebyeHuckelA, - real64 const DebyeHuckelB, - real64 const WATEQBDot ): - ReactionsBase::KernelWrapper( numPrimarySpecies, - numSecondarySpecies, - log10EqConst, - stoichMatrix, - chargePrimary, - chargeSec, - ionSizePrimary, - ionSizeSec, - DebyeHuckelA, - DebyeHuckelB, - WATEQBDot ) - {} - - /** - * @brief Construct a new update Concentrations object - * - * @param temperature - * @param totalConc - * @param dLog10PrimaryConc_dTotalConc - */ - void updateConcentrations( real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesTotalConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesContentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration ) const; -private: - - void assembleEquilibriumReactionSystem( real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesTotalConcentration, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - arraySlice2d< real64 > const & matrix, - arraySlice1d< real64 > const & rhs ) const; - - void computeSeondarySpeciesConcAndDerivative( real64 const temperature, - arraySlice1d< real64 const > const & log10PrimaryActCoeff, - arraySlice1d< real64 const > const & dLog10PrimaryActCoeff_dIonicStrength, - arraySlice1d< real64 const > const & log10SecActCoeff, - arraySlice1d< real64 const > const & dLog10SecActCoeff_dIonicStrength, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - arraySlice2d< real64 > const & dLog10SecConc_dLog10PrimaryConc ) const; - - void computeTotalConcAndDerivative( real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - arraySlice2d< real64 const > const & dLog10SecConc_dLog10PrimaryConc, - arraySlice1d< real64 > const & totalConc, - arraySlice2d< real64 > const & dTotalConc_dLog10PrimaryConc ) const; - - void updatePrimarySpeciesConcentrations( arraySlice1d< real64 const > const solution, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration ) const; - - void setInitialGuess( arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesTotalConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration ) const; - - static constexpr integer m_maxNumIterations = MultiFluidConstants::maxNewtonIterations; - static constexpr real64 m_newtonTol = 1e-6; - }; - -/** - * @brief Create an update kernel wrapper. - * @return the wrapper - */ - KernelWrapper createKernelWrapper() const; - -}; - - -} // end namespace chemicalReactions - -} // end namespace constitutive - -} // end namespace geos - -#endif //GEOS_CONSTITUTIVE_FLUID_CHEMICALREACTIONS_REQUILIBRIUMREACTIONS_HPP_ diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/KineticReactions.cpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/KineticReactions.cpp deleted file mode 100644 index 5009c9fbeae..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/KineticReactions.cpp +++ /dev/null @@ -1,205 +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 KineticReactions.cpp - */ - -#include "constitutive/fluid/multifluid/reactive/chemicalReactions/KineticReactions.hpp" -#include "functions/FunctionManager.hpp" -#include "common/Units.hpp" - -namespace geos -{ - -using namespace stringutilities; - -namespace constitutive -{ - -namespace chemicalReactions -{ - -KineticReactions::KineticReactions( string const & name, integer const numPrimarySpecies, integer const numSecSpecies, integer const numKineticReactions ): - ReactionsBase( name, numPrimarySpecies, numSecSpecies ), - m_numKineticReactions( numKineticReactions ) -{ - - // Stochiometric Matrix for the kinetic reactions (in terms of primary species only) - // First index: 0 = Ca(OH)2 dissolution, 1 = CaCO3 dissolution - // Second index: 0 = H+, 1 = HCO3-, 2 = Ca+2, 3 = SO4-2, 4 = Cl-, 5 = Mg+2, 6 = Na+1 - m_stoichMatrix.resize( m_numKineticReactions, m_numPrimarySpecies ); - m_stoichMatrix[0][0] = -2; - m_stoichMatrix[0][2] = 1; - m_stoichMatrix[1][0] = -1; - m_stoichMatrix[1][1] = 1; - m_stoichMatrix[1][2] = 1; - - // Equilibrium Constant - m_log10EqConst.resize( m_numKineticReactions ); - m_log10EqConst[0] = 20.19; - m_log10EqConst[1] = 1.32; - - // Rate Constant - // have to check the values as the functional form of the rate equation here differs from the implementation in GEOS - m_reactionRateConstant.resize( m_numKineticReactions ); - m_reactionRateConstant[0] = 9.95e-1; - m_reactionRateConstant[1] = 9.95e-3; - // Here we should either read the database or the input values. - - m_specificSurfaceArea = 1.0; -} - -KineticReactions::KernelWrapper KineticReactions::createKernelWrapper() const -{ - return KernelWrapper( m_numPrimarySpecies, - m_numSecondarySpecies, - m_numKineticReactions, - m_log10EqConst, - m_stoichMatrix, - m_chargePrimary, - m_chargeSec, - m_ionSizePrimary, - m_ionSizeSec, - m_DebyeHuckelA, - m_DebyeHuckelB, - m_WATEQBDot, - m_reactionRateConstant, - m_specificSurfaceArea ); -} - -// function to the reaction rate. Includes impact of temperature, concentration, surface area, volume fraction and porosity -void KineticReactions::KernelWrapper::computeReactionRates( real64 const & temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & reactionRates ) const -{ - /// 1. Create local vectors - stackArray1d< real64, ReactionsBase::maxNumPrimarySpecies > log10PrimaryActCoeff( m_numPrimarySpecies ); - stackArray1d< real64, ReactionsBase::maxNumSecondarySpecies > log10SecActCoeff( m_numSecondarySpecies ); - - real64 ionicStrength = 0.0; - stackArray1d< real64, ReactionsBase::maxNumPrimarySpecies > dIonicStrength_dPrimaryConcentration( m_numPrimarySpecies ); - stackArray1d< real64, ReactionsBase::maxNumPrimarySpecies > dLog10PrimaryActCoeff_dIonicStrength( m_numPrimarySpecies ); - stackArray1d< real64, ReactionsBase::maxNumSecondarySpecies > dLog10SecActCoeff_dIonicStrength( m_numSecondarySpecies ); - - /// 2. Compute activity coefficients - computeIonicStrength( primarySpeciesConcentration, - secondarySpeciesConcentration, - ionicStrength ); - - computeLog10ActCoefBDotModel( temperature, - ionicStrength, - log10PrimaryActCoeff, - dLog10PrimaryActCoeff_dIonicStrength, - log10SecActCoeff, - dLog10SecActCoeff_dIonicStrength ); - - - /// 3. Compute reaction rates - for( int iRxn = 0; iRxn < m_numKineticReactions; iRxn++ ) - { - real64 saturationIndex = -m_log10EqConst[iRxn]; - - for( int iPri = 0; iPri < m_numPrimarySpecies; ++iPri ) - { - saturationIndex += m_stoichMatrix[iRxn][iPri] * log10( primarySpeciesConcentration[iPri] ); - saturationIndex += m_stoichMatrix[iRxn][iPri] * log10PrimaryActCoeff[iPri]; - } - - reactionRates[iRxn] = m_specificSurfaceArea * (1.0 - pow( 10, saturationIndex ) ) * m_reactionRateConstant[iRxn]; - } -} - -} // end namespace chemicalReactions - -} // namespace constitutive - -} // end namespace geos - -/* - for( localIndex ir = 0; ir < NReaction; ++ir ) - { - - for( localIndex ic = 0; ic < kineticReaction.stochs.size(); ++ic ) - { - dSIndex[id] = kineticReaction.stochs[ic]; - - } - - - for( localIndex ic = 0; ic < NBasis; ++ic ) - { - - dKineticReactionRate_dConc[ir][ic] = S * kineticReaction.rateConst * rateTemp * pow( 10.0, SIndex ) * log( 10.0 ) * dSIndex[ic]; - - } - - } - - - for( localIndex ir = 0; ir < NReaction; ++ir ) - { - - for( localIndex i = 0; i < (kineticReaction.stochs).size(); ++i ) - { - - localIndex ic = basisSpeciesIndices[i]; - - kineticSpeciesReactionRate[ic] += -(kineticReaction.stochs)[i] * kineticReactionRate[ir]; - - for( localIndex id = 0; id < NBasis; ++id ) - { - - dKineticSpeciesReactionRate_dConc[ic][id] += -(kineticReaction.stochs)[i] * dKineticReactionRate_dConc[ir][id]; - - } - - } - - } - - } - // arraySlice1d< real64 const > const & concentration, - // arraySlice1d< real64 const > const & surfaceArea0, - // arraySlice1d< real64 const > const & volumeFraction0, - // arraySlice1d< real64 const > const & volumeFraction, - // real64 const & porosity0, - // real64 const & porosity, - // arraySlice1d< real64 > const & kineticReactionRate ) - // { - // for( localIndex ir = 0; ir < kineticReactionArray.size(); ++ir ) - // { - // const KineticReaction & kineticReaction = kineticReactionArray[ir]; - // const array1d< localIndex > & basisSpeciesIndices = kineticReaction.basisSpeciesIndices; - // // calculate saturation index - // real64 SIndex = -kineticReaction.logK; - // for( localIndex ic = 0; ic < kineticReaction.stochs.size(); ++ic ) - // { - // SIndex += kineticReaction.stochs[ic] * concentration[basisSpeciesIndices[ic] ]; // Check that the input "concentration" is - // // actually ln(activity - // coefficient*concentration) - // } - // // surface area is assumed to scale with the volume fraction. Check whether this is the volume fraction of the mineral - // // dissolving/precipitating. Not sure why porosity is included. - // real64 S = surfaceArea0[ir] * pow( volumeFraction[ir] / volumeFraction0[ir], 2.0/3.0 ) * pow( porosity / porosity0, 2.0/3.0 ); - // // computing the rate at the correct temperature. Looks like EQ36 database has it at 298.15 K - // real64 rateTemp = exp( -kineticReaction.E / RConst * (1.0 / units::convertCToK( temperature ) - 1.0 / 298.15)); - // real64 SS = (pow( 10.0, SIndex ) - 1.0); - // kineticReactionRate[ir] = S * kineticReaction.rateConst * rateTemp * SS; - //} - - - */ diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/KineticReactions.hpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/KineticReactions.hpp deleted file mode 100644 index 7c2ff5bf64a..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/KineticReactions.hpp +++ /dev/null @@ -1,124 +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 EquilibriumReaction.hpp - */ - -#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_REACTIVE_CHEMICALREACTIONS_REACTIONBASE_HPP_ -#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_REACTIVE_CHEMICALREACTIONS_REACTIONBASE_HPP_ - -#include "ReactionsBase.hpp" - -#include "constitutive/fluid/multifluid/Layouts.hpp" -#include "common/PhysicsConstants.hpp" - -namespace geos -{ - -namespace constitutive -{ - -namespace chemicalReactions -{ - -class KineticReactions : public ReactionsBase -{ -public: - - KineticReactions( string const & name, integer const numPrimarySpecies, integer const numSecSpecies, integer const numKineticReactions ); - - class KernelWrapper final : public ReactionsBase::KernelWrapper - { -public: - - static constexpr real64 RConst = constants::gasConstant; - - KernelWrapper( integer const numPrimarySpecies, - integer const numSecondarySpecies, - integer const numKineticReactions, - arrayView1d< real64 > const & log10EqConst, - arrayView2d< real64 > const & stoichMatrix, - arrayView1d< integer > const & chargePrimary, - arrayView1d< integer > const & chargeSec, - arrayView1d< real64 > const & ionSizePrimary, - arrayView1d< real64 > const & ionSizeSec, - real64 const DebyeHuckelA, - real64 const DebyeHuckelB, - real64 const WATEQBDot, - arrayView1d< real64 > const & reactionRateConstant, - real64 const specificSurfaceArea ): - ReactionsBase::KernelWrapper( numPrimarySpecies, - numSecondarySpecies, - log10EqConst, - stoichMatrix, - chargePrimary, - chargeSec, - ionSizePrimary, - ionSizeSec, - DebyeHuckelA, - DebyeHuckelB, - WATEQBDot ), - m_reactionRateConstant( reactionRateConstant ), - m_numKineticReactions( numKineticReactions ), - m_specificSurfaceArea( specificSurfaceArea ) - {} - - /** - * @brief Compute kinetic reaction rates. - * - * @param temperature - * @param primarySpeciesConcentration concentration of the primary species - * @param log10PrimaryActCoeff - * @param specificSurfaceArea the surface area available per unit volume - * @param reactionRates - */ - void computeReactionRates( real64 const & temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & reactionRates ) const; - -private: - - arrayView1d< real64 > m_reactionRateConstant; - - integer m_numKineticReactions; - - real64 m_specificSurfaceArea; - - }; - - /** - * @brief Create an update kernel wrapper. - * @return the wrapper - */ - KernelWrapper createKernelWrapper() const; - -private: - - array1d< real64 > m_reactionRateConstant; - - integer m_numKineticReactions; - - real64 m_specificSurfaceArea; -}; - -} // end namespace chemicalReactions - -} // end namespace constitutive - -} // end namespace geos - -#endif //GEOS_CONSTITUTIVE_FLUID_CHEMICALREACTIONS_REACTIONBASE_HPP_ diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/ReactionsBase.cpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/ReactionsBase.cpp deleted file mode 100644 index df579b3587e..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/ReactionsBase.cpp +++ /dev/null @@ -1,152 +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 EquilibriumReaction.cpp - */ - -#include "constitutive/fluid/multifluid/reactive/chemicalReactions/ReactionsBase.hpp" - -#include "functions/FunctionManager.hpp" - -namespace geos -{ - -using namespace stringutilities; - -namespace constitutive -{ - -namespace chemicalReactions -{ - -ReactionsBase::ReactionsBase( string const & name, integer const numPrimarySpecies, integer const numSecSpecies ): - m_name( name ), - m_numPrimarySpecies( numPrimarySpecies ), - m_numSecondarySpecies( numSecSpecies ) -{ - // Activity coefficient related constants - m_DebyeHuckelA = 0.5465; - m_DebyeHuckelB = 0.3346; - m_WATEQBDot = 0.0438; - - m_ionSizePrimary.resize( m_numPrimarySpecies ); - m_ionSizePrimary[0] = 9.00; - m_ionSizePrimary[1] = 4.00; - m_ionSizePrimary[2] = 6.00; - m_ionSizePrimary[3] = 4.00; - m_ionSizePrimary[4] = 3.00; - m_ionSizePrimary[5] = 8.00; - m_ionSizePrimary[6] = 4.00; - - m_ionSizeSec.resize( m_numSecondarySpecies ); - m_ionSizeSec[0] = 3.50; - m_ionSizeSec[1] = 3.00; - m_ionSizeSec[2] = 4.50; - m_ionSizeSec[3] = 3.00; - m_ionSizeSec[4] = 4.00; - m_ionSizeSec[5] = 3.00; - m_ionSizeSec[6] = 3.00; - m_ionSizeSec[7] = 4.00; - m_ionSizeSec[8] = 3.00; - m_ionSizeSec[9] = 3.00; - m_ionSizeSec[10] = 4.00; - - m_chargePrimary.resize( m_numPrimarySpecies ); - m_chargePrimary[0] = 1; - m_chargePrimary[1] = -1; - m_chargePrimary[2] = 2; - m_chargePrimary[3] = -2; - m_chargePrimary[4] = -1; - m_chargePrimary[5] = 2; - m_chargePrimary[6] = 1; - - m_chargeSec.resize( m_numSecondarySpecies ); - m_chargeSec[0] = -1; - m_chargeSec[1] = 0; - m_chargeSec[2] = -2; - m_chargeSec[3] = 0; - m_chargeSec[4] = 1; - m_chargeSec[5] = 0; - m_chargeSec[6] = 0; - m_chargeSec[7] = 1; - m_chargeSec[8] = 0; - m_chargeSec[9] = 0; - m_chargeSec[10] = -1; - -} - -void ReactionsBase::KernelWrapper::computeLog10ActCoefBDotModel( real64 const temperature, - real64 const ionicStrength, - arraySlice1d< real64 > const & log10PrimaryActCoeff, - arraySlice1d< real64 > const & dLog10PrimaryActCoeff_dIonicStrength, - arraySlice1d< real64 > const & log10SecActCoeff, - arraySlice1d< real64 > const & dLog10SecActCoeff_dIonicStrength ) const -{ - // Compute log10(ActivityCoefficient) for basis and dependent species along with their - // derivatives with respect to Ionic strength using the B-Dot Model - // which is the same as the Extended Debye-Huckel model in GEOS. - // localIndex const NBasis = m_numPrimarySpecies; - // localIndex const NDependent = m_numSecondarySpecies; - - GEOS_UNUSED_VAR( temperature ); - - for( localIndex i = 0; i < m_numPrimarySpecies; ++i ) - { - log10PrimaryActCoeff[i] = m_WATEQBDot * ionicStrength - m_DebyeHuckelA * m_chargePrimary[i] * m_chargePrimary[i] * sqrt( ionicStrength ) / - (1.0 + m_ionSizePrimary[i] * m_DebyeHuckelB * sqrt( ionicStrength )); - dLog10PrimaryActCoeff_dIonicStrength[i] = m_WATEQBDot - m_DebyeHuckelA * m_chargePrimary[i] * m_chargePrimary[i] * - (0.5 / sqrt( ionicStrength ) / (1.0 + m_ionSizePrimary[i] * m_DebyeHuckelB * sqrt( ionicStrength )) - 0.5 * m_ionSizePrimary[i] * m_DebyeHuckelB / - (1.0 + m_ionSizePrimary[i] * m_DebyeHuckelB * sqrt( ionicStrength )) / - (1.0 + m_ionSizePrimary[i] * m_DebyeHuckelB * sqrt( ionicStrength ))); -// log10PrimaryActCoeff[i] = 0; -// dLog10PrimaryActCoeff_dIonicStrength[i] = 0; - } - for( localIndex i = 0; i < m_numSecondarySpecies; ++i ) - { - log10SecActCoeff[i] = m_WATEQBDot * ionicStrength - m_DebyeHuckelA * m_chargeSec[i] * m_chargeSec[i] * sqrt( ionicStrength ) / - (1.0 + m_ionSizeSec[i] * m_DebyeHuckelB * sqrt( ionicStrength )); - dLog10SecActCoeff_dIonicStrength[i] = m_WATEQBDot - m_DebyeHuckelA * m_chargeSec[i] * m_chargeSec[i] * - (0.5 / sqrt( ionicStrength ) / (1.0 + m_ionSizeSec[i] * m_DebyeHuckelB * sqrt( ionicStrength )) - 0.5 * m_ionSizeSec[i] * m_DebyeHuckelB / - (1.0 + m_ionSizeSec[i] * m_DebyeHuckelB * sqrt( ionicStrength )) / - (1.0 + m_ionSizeSec[i] * m_DebyeHuckelB * sqrt( ionicStrength ))); -// log10SecActCoeff[i] = 0; -// dLog10SecActCoeff_dIonicStrength[i] = 0; - } -} - -void ReactionsBase::KernelWrapper::computeIonicStrength( arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - real64 & ionicStrength ) const -{ - //get ionic strength - ionicStrength = 0.0; - // Primary species - for( localIndex i = 0; i < m_numPrimarySpecies; ++i ) - { - ionicStrength += 0.5 * m_chargePrimary[i] * m_chargePrimary[i] * primarySpeciesConcentration[i]; - } - // Secondary species - for( int j = 0; j < m_numSecondarySpecies; ++j ) - { - ionicStrength += 0.5 * m_chargeSec[j] * m_chargeSec[j] * secondarySpeciesConcentration[j]; - } -} - -} // end namespace chemicalReactions - -} // namespace constitutive - -} // end namespace geos diff --git a/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/ReactionsBase.hpp b/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/ReactionsBase.hpp deleted file mode 100644 index 8b3e01b335f..00000000000 --- a/src/coreComponents/constitutive/fluid/multifluid/reactive/chemicalReactions/ReactionsBase.hpp +++ /dev/null @@ -1,170 +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 ReactionsBase.hpp - */ - -#ifndef GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_REACTIVE_CHEMICALREACTIONS_REACTIONSBASE_HPP_ -#define GEOS_CONSTITUTIVE_FLUID_MULTIFLUID_REACTIVE_CHEMICALREACTIONS_REACTIONSBASE_HPP_ - -#include "dataRepository/ObjectCatalog.hpp" - -namespace geos -{ - -namespace constitutive -{ - -namespace chemicalReactions -{ - -class ReactionsBase -{ -public: - - ReactionsBase( string const & name, integer const numPrimarySpecies, integer const numSecSpecies ); - - virtual ~ReactionsBase() = default; - - constexpr static integer maxNumPrimarySpecies = 12; - constexpr static integer maxNumSecondarySpecies = 15; - - string const & reactionName() const { return m_name; } - -protected: - /// Name the solubility model - string m_name; - - integer m_numPrimarySpecies; - - integer m_numSecondarySpecies; - - /// Array storing the name of the components - string_array m_componentNames; - - /// Array storing the component molar weights - array1d< real64 > m_componentMolarWeight; - - array1d< real64 > m_log10EqConst; - - array2d< real64 > m_stoichMatrix; - - array1d< integer > m_chargePrimary; - array1d< integer > m_chargeSec; - - array1d< real64 > m_ionSizePrimary; - array1d< real64 > m_ionSizeSec; - - real64 m_DebyeHuckelA; - real64 m_DebyeHuckelB; - real64 m_WATEQBDot; - - class KernelWrapper - { -public: - - /** - * @brief Construct a new Kernel Wrapper object - * - * @param log10EqConst - * @param stoichMatrix - * @param chargePrimary - * @param chargeSec - * @param m_ionSizePrimary - * @param ionSizeSec - * @param DebyeHuckelA - * @param DebyeHuckelB - * @param WATEQBDot - */ - KernelWrapper( integer const numPrimarySpecies, - integer const numSecondarySpecies, - arrayView1d< real64 > const & log10EqConst, - arrayView2d< real64 > const & stoichMatrix, - arrayView1d< integer > const & chargePrimary, - arrayView1d< integer > const & chargeSec, - arrayView1d< real64 > const & ionSizePrimary, - arrayView1d< real64 > const & ionSizeSec, - real64 const DebyeHuckelA, - real64 const DebyeHuckelB, - real64 const WATEQBDot ): - m_numPrimarySpecies( numPrimarySpecies ), - m_numSecondarySpecies( numSecondarySpecies ), - m_log10EqConst( log10EqConst ), - m_stoichMatrix( stoichMatrix ), - m_chargePrimary( chargePrimary ), - m_chargeSec( chargeSec ), - m_ionSizePrimary( ionSizePrimary ), - m_ionSizeSec( ionSizeSec ), - m_DebyeHuckelA( DebyeHuckelA ), - m_DebyeHuckelB( DebyeHuckelB ), - m_WATEQBDot( WATEQBDot ) - {} - -protected: - - /** - * @brief - * - * @param temperature - * @param ionicStrength - * @param log10PrimaryActCoeff - * @param dLog10PrimaryActCoeff_dIonicStrength - * @param log10SecActCoeff - * @param dLog10SecActCoeff_dIonicStrength - */ - void computeLog10ActCoefBDotModel( real64 const temperature, - real64 const ionicStrength, - arraySlice1d< real64 > const & log10PrimaryActCoeff, - arraySlice1d< real64 > const & dLog10PrimaryActCoeff_dIonicStrength, - arraySlice1d< real64 > const & log10SecActCoeff, - arraySlice1d< real64 > const & dLog10SecActCoeff_dIonicStrength ) const; - /** - * @brief - * - * @return - */ - void computeIonicStrength( arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - real64 & ionicStrength ) const; - - - /// Hard coding the example case - eventually would have to be changed such that it is read from an input file - integer m_numPrimarySpecies; // Currently not including H2O and O2gas - integer m_numSecondarySpecies; - - arrayView1d< real64 > m_log10EqConst; - arrayView2d< real64 > m_stoichMatrix; - - arrayView1d< integer > m_chargePrimary; - arrayView1d< integer > m_chargeSec; - - arrayView1d< real64 > m_ionSizePrimary; - arrayView1d< real64 > m_ionSizeSec; - - real64 m_DebyeHuckelA; - real64 m_DebyeHuckelB; - real64 m_WATEQBDot; - }; - -}; - -} // end namespace chemicalReactions - -} // end namespace constitutive - -} // end namespace geos - -#endif //GEOS_CONSTITUTIVE_FLUID_CHEMICALREACTIONS_REACTIONSBASE_HPP_ diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp index a64dfb08dad..b983063d391 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp @@ -17,8 +17,8 @@ * @file Layouts.hpp */ -#ifndef GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_LAYOUTS_HPP -#define GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_LAYOUTS_HPP +#ifndef GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUID_REACTIVEFLUIDLAYOUTS_HPP +#define GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUID_REACTIVEFLUIDLAYOUTS_HPP #include "common/DataTypes.hpp" #include "common/GeosxConfig.hpp" @@ -31,7 +31,7 @@ namespace geos namespace constitutive { -namespace reactiveFluid +namespace reactivefluid { struct DerivativeOffset { @@ -88,16 +88,11 @@ namespace reactiveFluid using LAYOUT_FLUID_DC = RAJA::PERM_JKI; #else - - /// Constitutive model phase property array layout - using LAYOUT_PHASE = RAJA::PERM_IJK; - /// Constitutive model phase property compositional derivative array layout - using LAYOUT_PHASE_DC = RAJA::PERM_IJKL; - + /// Constitutive model phase composition array layout - using LAYOUT_PHASE_COMP = RAJA::PERM_IJKL; + using LAYOUT_COMP = RAJA::PERM_IJ; /// Constitutive model phase composition compositional derivative array layout - using LAYOUT_PHASE_COMP_DC = RAJA::PERM_IJKLM; + using LAYOUT_COMP_DC = RAJA::PERM_IJK; /// Constitutive model fluid property array layout using LAYOUT_FLUID = RAJA::PERM_IJ; @@ -105,16 +100,12 @@ namespace reactiveFluid using LAYOUT_FLUID_DC = RAJA::PERM_IJK; #endif - - /// Constitutive model phase property unit stride dimension - static constexpr int USD_PHASE = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_PHASE{} ); - /// Constitutive model phase property compositional derivative unit stride dimension - static constexpr int USD_PHASE_DC = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_PHASE_DC{} ); + /// Constitutive model phase composition unit stride dimension - static constexpr int USD_PHASE_COMP = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_PHASE_COMP{} ); + static constexpr int USD_COMP = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_COMP{} ); /// Constitutive model phase composition compositional derivative unit stride dimension - static constexpr int USD_PHASE_COMP_DC = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_PHASE_COMP_DC{} ); + static constexpr int USD_COMP_DC = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_COMP_DC{} ); /// Constitutive model fluid property unit stride dimension static constexpr int USD_FLUID = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_FLUID{} ); @@ -125,4 +116,4 @@ namespace reactiveFluid } // namespace constitutive } // namespace geos -#endif //GEOS_CONSTITUTIVE_SINGLEFLUID_LAYOUTS_HPP +#endif //GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUID_REACTIVEFLUIDLAYOUTS_HPP diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index d0675e4123b..75cf36ab3a5 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -26,16 +26,19 @@ using namespace dataRepository; namespace constitutive { +namespace reactivefluid +{ + template< typename BASE > ReactiveSinglePhaseFluid< BASE >:: - ReactiveSinglePhaseFluid( string const & name, Group * const parent ): + ReactiveSinglePhaseFluid( string const & name, Group * const parent ) : BASE( name, parent ) { - registerWrapper( viewKeyStruct::chemicalSystemNameString(), &m_chemicalSystemName ). + registerWrapper( viewKeyStruct::chemicalSystemNameString(), &m_chemicalSystemType ). setInputFlag( InputFlags::REQUIRED ). - setDescription( "AMG smoother type. Available options are: " - "``" + EnumStrings< LinearSolverParameters::AMG::SmootherType >::concat( "|" ) + "``" ); + setDescription( "Chemical System type. Available options are: " + "``" + EnumStrings< ChemicalSystemType >::concat( "|" ) + "``" ); // For now this is being hardcoded. We will see where this should come from. m_numPrimarySpecies = 7; m_numSecondarySpecies = 11; @@ -49,25 +52,16 @@ template< typename BASE > std::unique_ptr< ConstitutiveBase > ReactiveSinglePhaseFluid< BASE >:: deliverClone( string const & name, Group * const parent ) const { - std::unique_ptr< ConstitutiveBase > clone = MultiFluidBase::deliverClone( name, parent ); + std::unique_ptr< ConstitutiveBase > clone = BASE::deliverClone( name, parent ); ReactiveSinglePhaseFluid & newConstitutiveRelation = dynamicCast< ReactiveSinglePhaseFluid & >( *clone ); - newConstitutiveRelation.createChemicalReactions(); - return clone; } template< typename BASE > void ReactiveSinglePhaseFluid< BASE >::postInputInitialization() -{ - BASE::postInputInitialization(); - GEOS_THROW_IF_NE_MSG( numFluidPhases(), 1, - GEOS_FMT( "{}: invalid number of phases", getFullName() ), - InputError ); - - createChemicalReactions(); -} +{} template< typename BASE > void ReactiveSinglePhaseFluid< BASE >::resizeFields( localIndex const size, localIndex const numPts ) @@ -82,10 +76,8 @@ void ReactiveSinglePhaseFluid< BASE >::resizeFields( localIndex const size, loca m_primarySpeciesTotalConcentration.resize( size, numPrimarySpecies ); } -template< typename BASE > -void ReactiveSinglePhaseFluid< BASE >::createChemicalReactions() -{} +} // namespace reactivefluid -} //namespace constitutive +} // namespace constitutive -} //namespace geos +} // namespace geos diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index 5078897cbe2..bceeeb862d8 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -25,7 +25,7 @@ #include "constitutive/ConstitutiveBase.hpp" #include "constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp" -#include "constitutive/HPCReact/src/reactions/bulkGeneric/Parameters.hpp" +#include "constitutive/HPCReact/src/reactions/bulkGeneric/ParametersPredefined.hpp" #include "constitutive/HPCReact/src/reactions/bulkGeneric/EquilibriumReactions.hpp" #include @@ -38,6 +38,12 @@ namespace constitutive namespace reactivefluid { +enum class ChemicalSystemType : integer +{ + carbonate, + ultramafic +}; + template< typename BASE > class ReactiveSinglePhaseFluid : public BASE { @@ -58,21 +64,10 @@ class ReactiveSinglePhaseFluid : public BASE arrayView2d< real64 const, compflow::USD_COMP > secondarySpeciesConcentration() const { return m_secondarySpeciesConcentration; } - arrayView2d< real64 const, compflow::USD_COMP > kineticReactionRates() const - { return m_kineticReactionRates; } - integer numPrimarySpecies() const { return m_numPrimarySpecies; } integer numSecondarySpecies() const { return m_numSecondarySpecies; } - integer numKineticReactions() const { return m_numKineticReactions; } - - enum class ChemicalSystemType : integer - { - carbonate, - ultramafic - }; - /** * @brief Kernel wrapper class for ReactiveSinglePhaseFluid. */ @@ -83,21 +78,33 @@ class ReactiveSinglePhaseFluid : public BASE using EquilibriumReactionsType = hpcReact::bulkGeneric::EquilibriumReactions< real64, integer, localIndex >; + void computeChemistry( real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, reactivefluid::USD_COMP - 1 > const & primarySpeciesTotalConcentration, + arraySlice1d< real64, reactivefluid::USD_COMP - 1 > const & primarySpeciesConcentration, + arraySlice1d< real64, reactivefluid::USD_COMP - 1 > const & secondarySpeciesConcentration ) const; + protected: - arrayView2d< real64, reactiveFluid::USD_COMP > m_primarySpeciesConcentration; + integer m_numPrimarySpecies; + + integer m_numSecondarySpecies; + + arrayView2d< real64, reactivefluid::USD_COMP > m_primarySpeciesConcentration; - arrayView2d< real64, reactiveFluid::USD_COMP > m_secondarySpeciesConcentration; + arrayView2d< real64, reactivefluid::USD_COMP > m_secondarySpeciesConcentration; - arrayView2d< real64, reactiveFluid::USD_COMP > m_primarySpeciesTotalConcentration; + arrayView2d< real64, reactivefluid::USD_COMP > m_primarySpeciesTotalConcentration; - arrayView2d< real64, reactiveFluid::USD_COMP > m_kineticReactionRates; + arrayView2d< real64, reactivefluid::USD_COMP > m_kineticReactionRates; }; struct viewKeyStruct : ConstitutiveBase::viewKeyStruct - {}; + { + static constexpr char const * chemicalSystemNameString() { return "chemicalSystemType"; } + }; protected: @@ -105,6 +112,10 @@ class ReactiveSinglePhaseFluid : public BASE virtual void resizeFields( localIndex const size, localIndex const numPts ) override; + integer m_numPrimarySpecies; + + integer m_numSecondarySpecies; + array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_primarySpeciesConcentration; array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_secondarySpeciesConcentration; @@ -116,17 +127,18 @@ class ReactiveSinglePhaseFluid : public BASE ChemicalSystemType m_chemicalSystemType; }; +template inline void -ReactiveSinglePhaseFluid::KernelWrapper:: +ReactiveSinglePhaseFluid< BASE >::KernelWrapper:: computeChemistry( real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesTotalConcentration, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & kineticReactionRates ) const + arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration ) const { + GEOS_UNUSED_VAR( pressure ); auto params = hpcReact::bulkGeneric::carbonateSystem; - EquilibriumReactionsType::enforceEquilibrium_Extents( temperature, params, speciesConcentration0, speciesConcentration ); + EquilibriumReactionsType::enforceEquilibrium_Extents( temperature, params, primarySpeciesAggregateConcentration, primarySpeciesConcentration ); } ENUM_STRINGS( ChemicalSystemType, diff --git a/src/coreComponents/constitutiveDrivers/CMakeLists.txt b/src/coreComponents/constitutiveDrivers/CMakeLists.txt index 4791a46bf02..30373efba0b 100644 --- a/src/coreComponents/constitutiveDrivers/CMakeLists.txt +++ b/src/coreComponents/constitutiveDrivers/CMakeLists.txt @@ -25,7 +25,6 @@ set( constitutiveDrivers_headers fluid/multiFluid/LogLevelsInfo.hpp fluid/multiFluid/PVTDriver.hpp fluid/multiFluid/PVTDriverRunTest.hpp - fluid/multiFluid/reactive/ReactiveFluidDriver.hpp relativePermeability/RelpermDriver.hpp relativePermeability/RelpermDriverRunTest.hpp solid/TriaxialDriver.hpp @@ -43,7 +42,6 @@ set( constitutiveDrivers_sources fluid/multiFluid/compositional/PVTDriverRunTestCompositionalThreePhaseLohrenzBrayClarkViscosity.cpp fluid/multiFluid/compositional/PVTDriverRunTestCompositionalTwoPhaseConstantViscosity.cpp fluid/multiFluid/compositional/PVTDriverRunTestCompositionalTwoPhaseLohrenzBrayClarkViscosity.cpp - fluid/multiFluid/reactive/ReactiveFluidDriver.cpp relativePermeability/RelpermDriver.cpp relativePermeability/RelpermDriverBrooksCoreyBakerRunTest.cpp relativePermeability/RelpermDriverBrooksCoreyStone2RunTest.cpp diff --git a/src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt b/src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt index f59c739a956..f5012615bf7 100644 --- a/src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt +++ b/src/coreComponents/unitTests/constitutiveTests/CMakeLists.txt @@ -31,9 +31,6 @@ set( gtest_pvt_xmls testPVT_ThreePhaseCompositional.xml ) -set( gtest_reactivefluid_xmls - testReactiveFluid.xml ) - set( tplDependencyList ${parallelDeps} gtest ) set( dependencyList mainInterface ) @@ -80,17 +77,4 @@ foreach(test ${gtest_pvt_xmls}) get_filename_component( test_name ${test} NAME_WE ) geos_add_test( NAME ${test_name} COMMAND testPVT -i ${CMAKE_CURRENT_LIST_DIR}/${test} ) -endforeach() - - -# Add reactivefluiddriver xml based tests -blt_add_executable( NAME testReactiveFluid - SOURCES testReactiveFluid.cpp - OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY} - DEPENDS_ON ${dependencyList} "-lz" ${tplDependencyList} ) - -foreach(test ${gtest_reactivefluid_xmls}) - get_filename_component( test_name ${test} NAME_WE ) - geos_add_test( NAME ${test_name} - COMMAND testReactiveFluid -i ${CMAKE_CURRENT_LIST_DIR}/${test} ) endforeach() \ No newline at end of file From d61e9804ae4c3e51505579219ef64017ef8c9b06 Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Wed, 2 Apr 2025 18:07:20 -0700 Subject: [PATCH 08/12] finally compiles --- .../constitutive/CMakeLists.txt | 1 + .../reactivefluid/ReactiveFluidFields.hpp | 74 +++++++++++++++++++ .../ReactiveSinglePhaseFluid.cpp | 1 + .../ReactiveSinglePhaseFluid.hpp | 2 +- 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index 1e03c4a0086..51424ec1fc0 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -111,6 +111,7 @@ set( constitutive_headers fluid/multifluid/compositional/CompositionalMultiphaseFluid.hpp fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp + fluid/reactivefluid/ReactiveFluidFields.hpp fluid/reactivefluid/ReactiveFluidLayouts.hpp fluid/singlefluid/CompressibleSinglePhaseFluid.hpp fluid/singlefluid/ParticleFluid.hpp diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp new file mode 100644 index 00000000000..c23e9bb3d8b --- /dev/null +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp @@ -0,0 +1,74 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactiveFluidFields.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUID_REACTIVEFLUIDFIELDS_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUID_REACTIVEFLUIDFIELDS_HPP_ + +#include "constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp" +#include "mesh/MeshFields.hpp" + +namespace geos +{ + +namespace fields +{ + +namespace reactivefluid +{ + +using array2dLayoutComp = array2d< real64, constitutive::reactivefluid::LAYOUT_COMP >; + +DECLARE_FIELD( primarySpeciesConcentration, + "primarySpeciesConcentration", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "primarySpeciesConcentration" ); + +DECLARE_FIELD( primarySpeciesTotalConcentration, + "primarySpeciesTotalConcentration", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "primarySpeciesTotalConcentration" ); + +DECLARE_FIELD( secondarySpeciesConcentration, + "secondarySpeciesConcentration", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "secondarySpeciesConcentration" ); + +DECLARE_FIELD( kineticReactionRates, + "kineticReactionRates", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "kineticReactionRates" ); +} + +} + +} + +#endif // GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUID_REACTIVEFLUIDFIELDS_HPP_ diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index 75cf36ab3a5..ffb0c7ef381 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -17,6 +17,7 @@ * @file ReactiveSinglePhaseFluid.cpp */ #include "ReactiveSinglePhaseFluid.hpp" +#include "ReactiveFluidFields.hpp" namespace geos { diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index bceeeb862d8..d1077b601ca 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -136,7 +136,7 @@ ReactiveSinglePhaseFluid< BASE >::KernelWrapper:: arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration ) const { - GEOS_UNUSED_VAR( pressure ); + GEOS_UNUSED_VAR( pressure, secondarySpeciesConcentration ); auto params = hpcReact::bulkGeneric::carbonateSystem; EquilibriumReactionsType::enforceEquilibrium_Extents( temperature, params, primarySpeciesAggregateConcentration, primarySpeciesConcentration ); } From 9e9b518dd20a97ea324f60bb6f121a34db3c5565 Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Fri, 4 Apr 2025 17:52:23 -0700 Subject: [PATCH 09/12] added dispatch. --- .../ReactiveSinglePhaseFluid.cpp | 24 +++++++ .../ReactiveSinglePhaseFluid.hpp | 67 +++++++++++++------ .../singlePhase/ReactiveFluidUpdateKernel.hpp | 59 ++++++++++++++++ 3 files changed, 131 insertions(+), 19 deletions(-) create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ReactiveFluidUpdateKernel.hpp diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index ffb0c7ef381..cb0f8cfb896 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -30,6 +30,8 @@ namespace constitutive namespace reactivefluid { +using namespace hpcReact::bulkGeneric; + template< typename BASE > ReactiveSinglePhaseFluid< BASE >:: ReactiveSinglePhaseFluid( string const & name, Group * const parent ) : @@ -77,6 +79,28 @@ void ReactiveSinglePhaseFluid< BASE >::resizeFields( localIndex const size, loca m_primarySpeciesTotalConcentration.resize( size, numPrimarySpecies ); } +template< typename BASE > +std::variant< KernelWrapper< carbonateSystemType >, + KernelWrapper< simpleTestType > > +ReactiveSinglePhaseFluid< BASE >createKernelWrapper() const +{ + switch ( m_chemicalSystemType ) + { + case ChemicalSystemType::carbonates: + return KernelWrapper< hpcReact::bubulkGeneric::carbonateSystemType >( m_primarySpeciesConcentration, + m_secondarySpeciesConcentration, + m_primarySpeciesTotalConcentration, + m_numSecondarySpecies, + carbonateSystem ); + default: + return KernelWrapper< hpcReact::bubulkGeneric::simpleTestType >( m_primarySpeciesConcentration, + m_secondarySpeciesConcentration, + m_primarySpeciesTotalConcentration, + m_numSecondarySpecies, + simpleTest ); + } +} + } // namespace reactivefluid } // namespace constitutive diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index d1077b601ca..03117773612 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -68,14 +68,33 @@ class ReactiveSinglePhaseFluid : public BASE integer numSecondarySpecies() const { return m_numSecondarySpecies; } + auto createKernelWraper() const + { + + + std::variant< KernelWrapper< hpcReact::bubulkGeneric::carbonateSystemType >, + KernelWrapper< hpcReact::bubulkGeneric::simpleTestType > > + createKernelWrapper() const; + /** * @brief Kernel wrapper class for ReactiveSinglePhaseFluid. */ + template< typename REACTION_PARAMS_TYPE > class KernelWrapper : public BASE::KernelWrapper { public: + KernelWrapper( arrayView2d< real64, reactivefluid::USD_COMP > const & secondarySpeciesConcentration, + integer const numPrimarySpecies, + integer const numSecondarySpecies, + REACTION_PARAMS_TYPE params ) : + m_secondarySpeciesConcentration( secondarySpeciesConcentration ), + m_numPrimarySpecies( numPrimarySpecies ), + m_numSecondarySpecies( numSecondarySpecies ), + m_params( params ) + {} + using EquilibriumReactionsType = hpcReact::bulkGeneric::EquilibriumReactions< real64, integer, localIndex >; void computeChemistry( real64 const pressure, @@ -90,15 +109,11 @@ class ReactiveSinglePhaseFluid : public BASE integer m_numSecondarySpecies; - arrayView2d< real64, reactivefluid::USD_COMP > m_primarySpeciesConcentration; - arrayView2d< real64, reactivefluid::USD_COMP > m_secondarySpeciesConcentration; - arrayView2d< real64, reactivefluid::USD_COMP > m_primarySpeciesTotalConcentration; - arrayView2d< real64, reactivefluid::USD_COMP > m_kineticReactionRates; - + REACTION_PARAMS_TYPE m_params; }; struct viewKeyStruct : ConstitutiveBase::viewKeyStruct @@ -116,29 +131,43 @@ class ReactiveSinglePhaseFluid : public BASE integer m_numSecondarySpecies; - array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_primarySpeciesConcentration; - array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_secondarySpeciesConcentration; - array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_primarySpeciesTotalConcentration; - array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_kineticReactionRates; ChemicalSystemType m_chemicalSystemType; }; -template +template< typename BASE > +inline void +ReactiveSinglePhaseFluid< BASE >::KernelWrapper:: + enforceEquilibrium( real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration ) const +{ + GEOS_UNUSED_VAR( pressure ); + // 1. We enforce equilibrium + EquilibriumReactionsType::enforceEquilibrium_Extents( temperature, m_params, primarySpeciesAggregateConcentration, primarySpeciesConcentration ); + // 2. We calculate the secondary species concentration + speciesUtilities::calculateLogSecondarySpeciesConcentration( m_params, primarySpeciesConcentration, secondarySpeciesConcentration ); +} + +template< typename BASE > inline void ReactiveSinglePhaseFluid< BASE >::KernelWrapper:: - computeChemistry( real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration ) const + computeReactionRates( real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration ) const { - GEOS_UNUSED_VAR( pressure, secondarySpeciesConcentration ); - auto params = hpcReact::bulkGeneric::carbonateSystem; - EquilibriumReactionsType::enforceEquilibrium_Extents( temperature, params, primarySpeciesAggregateConcentration, primarySpeciesConcentration ); + GEOS_UNUSED_VAR( pressure ); + // 1. We enforce equilibrium + EquilibriumReactionsType::enforceEquilibrium_Extents( temperature, m_params, primarySpeciesAggregateConcentration, primarySpeciesConcentration ); + // 2. We calculate the secondary species concentration + speciesUtilities::calculateLogSecondarySpeciesConcentration( m_params, primarySpeciesConcentration, secondarySpeciesConcentration ); } ENUM_STRINGS( ChemicalSystemType, @@ -151,4 +180,4 @@ ENUM_STRINGS( ChemicalSystemType, } // namespace geos -#endif //GEOS_CONSTITUTIVE_FLUID_ReactiveSinglePhaseFluid_HPP +#endif // GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUID_REACTIVESINGLEPHASEFLUID_HPP_ diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ReactiveFluidUpdateKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ReactiveFluidUpdateKernel.hpp new file mode 100644 index 00000000000..c985d5062d2 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ReactiveFluidUpdateKernel.hpp @@ -0,0 +1,59 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 FluidUpdateKernel.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVEFLUIDUPDATEKERNEL_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVEFLUIDUPDATEKERNEL_HPP + +#include "common/DataTypes.hpp" +#include "common/GEOS_RAJA_Interface.hpp" + +namespace geos +{ + +namespace reactiveTransportKernels +{ + +/******************************** FluidUpdateKernel ********************************/ + +struct FluidUpdateKernel +{ + template< typename FLUID > + static void launch( FLUID const & fluid, + arrayView1d< real64 const > const & pres, + arrayView1d< real64 const > const & temp ) + { + std::visit( [&]( auto const fluidWrapper ) + { + // For the reactive fluid, we need to + forAll< parallelDevicePolicy<> >( fluidWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) + { + for( localIndex q = 0; q < fluidWrapper.numGauss(); ++q ) + { + fluidWrapper.update( k, q, pres[k], temp[k] ); + } + } ); + }, fluid.createKernelWrapper()); + } +}; + +} // namespace reactiveTransportKernels + +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVEFLUIDUPDATEKERNEL_HPP From d04535bc18f9809df10dac475ba16d36621e9da1 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Mon, 14 Apr 2025 11:14:15 -0700 Subject: [PATCH 10/12] changed the names of some fields --- .../SinglePhaseReactiveTransport.cpp | 20 +++++----- .../SinglePhaseReactiveTransportFields.hpp | 12 +++--- .../reactive/AccumulationKernels.hpp | 37 ++++++++++--------- .../reactive/ResidualNormKernel.hpp | 20 +++++----- 4 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index c09bebd7adb..705ae361db5 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -126,10 +126,10 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) subRegion.registerField< logPrimarySpeciesConcentration_n >( getName() ). reference().resizeDimension< 1 >( m_numPrimarySpecies ); - subRegion.registerField< totalPrimarySpeciesAmount >( getName() ). + subRegion.registerField< primarySpeciesAggregateMole >( getName() ). reference().resizeDimension< 1 >( m_numPrimarySpecies ); - subRegion.registerField< totalPrimarySpeciesAmount_n >( getName() ). + subRegion.registerField< primarySpeciesAggregateMole_n >( getName() ). reference().resizeDimension< 1 >( m_numPrimarySpecies ); subRegion.registerField< bcLogPrimarySpeciesConcentration >( getName() ). @@ -380,8 +380,8 @@ void SinglePhaseReactiveTransport::updateSpeciesAmount( ElementSubRegionBase & s { GEOS_MARK_FUNCTION; - arrayView2d< real64, compflow::USD_COMP > const totalPrimarySpeciesAmount = subRegion.getField< fields::flow::totalPrimarySpeciesAmount >(); - arrayView2d< real64, compflow::USD_COMP > const totalPrimarySpeciesAmount_n = subRegion.getField< fields::flow::totalPrimarySpeciesAmount_n >(); + arrayView2d< real64, compflow::USD_COMP > const primarySpeciesAggregateMole = subRegion.getField< fields::flow::primarySpeciesAggregateMole >(); + arrayView2d< real64, compflow::USD_COMP > const primarySpeciesAggregateMole_n = subRegion.getField< fields::flow::primarySpeciesAggregateMole_n >(); CoupledSolidBase const & porousSolid = getConstitutiveModel< CoupledSolidBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ) ); @@ -400,10 +400,10 @@ void SinglePhaseReactiveTransport::updateSpeciesAmount( ElementSubRegionBase & s { for( integer is = 0; is < m_numPrimarySpecies; ++is ) { - totalPrimarySpeciesAmount[ei][is] = porosity[ei][0] * ( volume[ei] + deltaVolume[ei] ) * primarySpeciesAggregateConcentration[ei][is]; + primarySpeciesAggregateMole[ei][is] = porosity[ei][0] * ( volume[ei] + deltaVolume[ei] ) * primarySpeciesAggregateConcentration[ei][is]; - if( isZero( totalPrimarySpeciesAmount_n[ei][is] ) ) - totalPrimarySpeciesAmount_n[ei][is] = porosity_n[ei][0] * volume[ei] * primarySpeciesAggregateConcentration_n[ei][is]; + if( isZero( primarySpeciesAggregateMole_n[ei][is] ) ) + primarySpeciesAggregateMole_n[ei][is] = porosity_n[ei][0] * volume[ei] * primarySpeciesAggregateConcentration_n[ei][is]; } } ); } @@ -996,9 +996,9 @@ void SinglePhaseReactiveTransport::saveConvergedState( ElementSubRegionBase & su { SinglePhaseBase::saveConvergedState( subRegion ); - arrayView2d< real64 const, compflow::USD_COMP > const totalPrimarySpeciesAmount = subRegion.template getField< fields::flow::totalPrimarySpeciesAmount >(); - arrayView2d< real64, compflow::USD_COMP > const totalPrimarySpeciesAmount_n = subRegion.template getField< fields::flow::totalPrimarySpeciesAmount_n >(); - totalPrimarySpeciesAmount_n.setValues< parallelDevicePolicy<> >( totalPrimarySpeciesAmount ); + arrayView2d< real64 const, compflow::USD_COMP > const primarySpeciesAggregateMole = subRegion.template getField< fields::flow::primarySpeciesAggregateMole >(); + arrayView2d< real64, compflow::USD_COMP > const primarySpeciesAggregateMole_n = subRegion.template getField< fields::flow::primarySpeciesAggregateMole_n >(); + primarySpeciesAggregateMole_n.setValues< parallelDevicePolicy<> >( primarySpeciesAggregateMole ); } void SinglePhaseReactiveTransport::assembleEDFMFluxTerms( real64 const GEOS_UNUSED_PARAM( time_n ), diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp index 96161f5b71c..3aa6c8f8cd4 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp @@ -59,21 +59,21 @@ DECLARE_FIELD( bcLogPrimarySpeciesConcentration, WRITE_AND_READ, "Boundary condition for natural log of primary species concentration (molarity)" ); -DECLARE_FIELD( totalPrimarySpeciesAmount, - "totalPrimarySpeciesAmount", +DECLARE_FIELD( primarySpeciesAggregateMole, + "primarySpeciesAggregateMole", array2dLayoutComp, 0, LEVEL_0, WRITE_AND_READ, - "Total amount of species (both primary and secondary) that contain the ion in the primary species (mole)" ); + "Aggregate amount of primary species in mole" ); -DECLARE_FIELD( totalPrimarySpeciesAmount_n, - "totalPrimarySpeciesAmount_n", +DECLARE_FIELD( primarySpeciesAggregateMole_n, + "primarySpeciesAggregateMole_n", array2dLayoutComp, 0, LEVEL_0, WRITE_AND_READ, - "Total amount of species (both primary and secondary) that contain the ion in the primary species (mole) at the previous converged time step" ); + "Aggregate amount of primary species in mole at the previous converged time step" ); DECLARE_FIELD( dMobility_dLogPrimaryConc, "dMobility_dLogPrimaryConc", diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp index b205f7b9842..188939ac350 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp @@ -90,10 +90,10 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU m_primarySpeciesAggregateConcentration( fluid.primarySpeciesAggregateConcentration() ), // m_dPrimarySpeciesAggregateConcentration_dPres( fluid.dPrimarySpeciesAggregateConcentration_dPres() ), m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc( fluid.dPrimarySpeciesAggregateConcentration_dLogPrimaryConc() ), - m_kineticReactionRates( fluid.kineticReactionRates() ), - // m_dPrimarySpeciesTotalKineticRate_dPres( fluid.dPrimarySpeciesTotalKineticRate_dPres() ), - // m_dPrimarySpeciesTotalKineticRate_dLogPrimaryConc( fluid.dPrimarySpeciesTotalKineticRate_dLogPrimaryConc() ), - m_totalPrimarySpeciesAmount_n( subRegion.template getField< fields::flow::totalPrimarySpeciesAmount_n >() ) + m_primarySpeciesAggregateKineticRate( fluid.kineticReactionRates() ), + // m_dPrimarySpeciesAggregateKineticRate_dPres( fluid.dPrimarySpeciesAggregateKineticRate_dPres() ), + // m_dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc( fluid.dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc() ), + m_primarySpeciesAggregateMole_n( subRegion.template getField< fields::flow::primarySpeciesAggregateMole_n >() ) {} /** @@ -159,7 +159,7 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU void computeAccumulation( localIndex const ei, StackVariables & stack ) const { - // Residual[is] += (totalPrimarySpeciesConcentration[is] * stack.poreVolume - totalPrimarySpeciesAmount_n[is]) + // Residual[is] += (primarySpeciesAggregateConcentration[is] * stack.poreVolume - primarySpeciesAggregateMole_n[is]) // - dt * m_volume * primarySpeciesKineticRate[is] // To Check: what's the unit of the kinetic rate Base::computeAccumulation( ei, stack ); @@ -177,12 +177,13 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU { // Step 2: assemble the accumulation term of the species mass balance equation // Step 2.1: residual - // Primary species amount in pore volume - stack.localResidual[is+numEqn-numSpecies] -= m_totalPrimarySpeciesAmount_n[ei][is]; + // Primary species mole amount in pore volume + stack.localResidual[is+numEqn-numSpecies] -= m_primarySpeciesAggregateMole_n[ei][is]; stack.localResidual[is+numEqn-numSpecies] += m_primarySpeciesAggregateConcentration[ei][is] * stack.poreVolume; // // Reaction term - // stack.localResidual[is+numEqn-numSpecies] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * m_primarySpeciesTotalKineticRate[is]; + // stack.localResidual[is+numEqn-numSpecies] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * + // m_primarySpeciesAggregateKineticRate[is]; // Step 2.1: jacobian // Drivative of primary species amount in pore volume wrt pressure @@ -227,8 +228,8 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // - the total mass balance equations (i = 0) Base::complete( ei, stack ); - // Step 2: assemble the primary species amount balance equation - // - the species amount balance equations (i = numEqn-numSpecies to i = numEqn-1) + // Step 2: assemble the primary species mole amount balance equation + // - the species mole amount balance equations (i = numEqn-numSpecies to i = numEqn-1) integer const beginRowSpecies = numEqn-numSpecies; for( integer i = 0; i < numSpecies; ++i ) { @@ -268,17 +269,17 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // View on the derivatives of total ion concentration for the primary species wrt log of primary species concentration arrayView3d< real64 const, compflow::USD_COMP_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; - // View on the total kinetic rate of primary species from all reactions - arrayView2d< real64 const, compflow::USD_COMP > m_kineticReactionRates; + // View on the aggregate kinetic rate of primary species from all reactions + arrayView2d< real64 const, compflow::USD_COMP > m_primarySpeciesAggregateKineticRate; - // // View on the derivatives of total kinetic rate of primary species wrt pressure - // arrayView2d< real64 const, compflow::USD_COMP > m_dPrimarySpeciesTotalKineticRate_dPres; + // // View on the derivatives of aggregate kinetic rate of primary species wrt pressure + // arrayView2d< real64 const, compflow::USD_COMP > m_dPrimarySpeciesAggregateKineticRate_dPres; - // // View on the derivatives of total kinetic rate of primary species wrt log of primary species concentration - // arrayView3d< real64 const, compflow::USD_COMP_DC > m_dPrimarySpeciesTotalKineticRate_dLogPrimaryConc; + // // View on the derivatives of aggregate kinetic rate of primary species wrt log of primary species concentration + // arrayView3d< real64 const, compflow::USD_COMP_DC > m_dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc; - // View on primary species amount (moles) from previous time step - arrayView2d< real64 const, compflow::USD_COMP > m_totalPrimarySpeciesAmount_n; + // View on primary species mole amount from previous time step + arrayView2d< real64 const, compflow::USD_COMP > m_primarySpeciesAggregateMole_n; }; /** diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ResidualNormKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ResidualNormKernel.hpp index 5ce9205256d..c9fc35acce1 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ResidualNormKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ResidualNormKernel.hpp @@ -58,7 +58,7 @@ class IsothermalResidualNormKernel : public physicsSolverBaseKernels::ResidualNo minNormalizer ), m_numPrimarySpecies( numPrimarySpecies ), m_mass_n( subRegion.template getField< fields::flow::mass_n >() ), - m_totalPrimarySpeciesAmount_n( subRegion.getField< fields::flow::totalPrimarySpeciesAmount_n >() ) + m_primarySpeciesAggregateMole_n( subRegion.getField< fields::flow::primarySpeciesAggregateMole_n >() ) {} GEOS_HOST_DEVICE @@ -77,7 +77,7 @@ class IsothermalResidualNormKernel : public physicsSolverBaseKernels::ResidualNo // step 2: species amount residuals for( integer idof = 0; idof < m_numPrimarySpecies; ++idof ) { - real64 const speciesAmountNormalizer = LvArray::math::max( m_minNormalizer, m_totalPrimarySpeciesAmount_n[ei][idof] ); + real64 const speciesAmountNormalizer = LvArray::math::max( m_minNormalizer, m_primarySpeciesAggregateMole_n[ei][idof] ); real64 const valAmount = LvArray::math::abs( m_localResidual[stack.localRow + idof + 1] ) / speciesAmountNormalizer; if( valAmount > stack.localValue[1] ) { @@ -99,7 +99,7 @@ class IsothermalResidualNormKernel : public physicsSolverBaseKernels::ResidualNo // step 2: species amount residuals for( integer idof = 0; idof < m_numPrimarySpecies; ++idof ) { - real64 const speciesAmountNormalizer = LvArray::math::max( m_minNormalizer, m_totalPrimarySpeciesAmount_n[ei][idof] ); + real64 const speciesAmountNormalizer = LvArray::math::max( m_minNormalizer, m_primarySpeciesAggregateMole_n[ei][idof] ); stack.localValue[1] += m_localResidual[stack.localRow + idof + 1] * m_localResidual[stack.localRow + idof + 1]; stack.localNormalizer[1] += speciesAmountNormalizer; @@ -115,8 +115,8 @@ class IsothermalResidualNormKernel : public physicsSolverBaseKernels::ResidualNo /// View on mass at the previous converged time step arrayView1d< real64 const > const m_mass_n; - // View on primary species amount (moles) from previous time step - arrayView2d< real64 const, compflow::USD_COMP > m_totalPrimarySpeciesAmount_n; + // View on primary species aggregate amount (moles) from previous time step + arrayView2d< real64 const, compflow::USD_COMP > m_primarySpeciesAggregateMole_n; }; @@ -147,7 +147,7 @@ class ThermalResidualNormKernel : public physicsSolverBaseKernels::ResidualNormK minNormalizer ), m_numPrimarySpecies( numPrimarySpecies ), m_mass_n( subRegion.template getField< fields::flow::mass_n >() ), - m_totalPrimarySpeciesAmount_n( subRegion.getField< fields::flow::totalPrimarySpeciesAmount_n >() ), + m_primarySpeciesAggregateMole_n( subRegion.getField< fields::flow::primarySpeciesAggregateMole_n >() ), m_energy_n( subRegion.template getField< fields::flow::energy_n >() ) {} @@ -185,7 +185,7 @@ class ThermalResidualNormKernel : public physicsSolverBaseKernels::ResidualNormK // step 3: species amount residuals for( integer idof = 0; idof < m_numPrimarySpecies; ++idof ) { - real64 const speciesAmountNormalizer = LvArray::math::max( m_minNormalizer, m_totalPrimarySpeciesAmount_n[ei][idof] ); + real64 const speciesAmountNormalizer = LvArray::math::max( m_minNormalizer, m_primarySpeciesAggregateMole_n[ei][idof] ); real64 const valAmount = LvArray::math::abs( m_localResidual[stack.localRow + idof + 2] ) / speciesAmountNormalizer; if( valAmount > stack.localValue[2] ) { @@ -214,7 +214,7 @@ class ThermalResidualNormKernel : public physicsSolverBaseKernels::ResidualNormK // step 3: species amount residuals for( integer idof = 0; idof < m_numPrimarySpecies; ++idof ) { - real64 const speciesAmountNormalizer = LvArray::math::max( m_minNormalizer, m_totalPrimarySpeciesAmount_n[ei][idof] ); + real64 const speciesAmountNormalizer = LvArray::math::max( m_minNormalizer, m_primarySpeciesAggregateMole_n[ei][idof] ); stack.localValue[2] += m_localResidual[stack.localRow + idof + 2] * m_localResidual[stack.localRow + idof + 2]; stack.localNormalizer[2] += speciesAmountNormalizer; @@ -230,8 +230,8 @@ class ThermalResidualNormKernel : public physicsSolverBaseKernels::ResidualNormK /// View on mass at the previous converged time step arrayView1d< real64 const > const m_mass_n; - // View on primary species amount (moles) from previous time step - arrayView2d< real64 const, compflow::USD_COMP > m_totalPrimarySpeciesAmount_n; + // View on primary species aggregate amount (moles) from previous time step + arrayView2d< real64 const, compflow::USD_COMP > m_primarySpeciesAggregateMole_n; /// View on energy at the previous converged time step arrayView1d< real64 const > const m_energy_n; From 11c60b27933f4508a7b0b92c25223f642c270ab0 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Thu, 24 Apr 2025 15:40:06 -0700 Subject: [PATCH 11/12] plugged in the equilibrium reaction to the transport solver --- .../constitutive/CMakeLists.txt | 7 +- .../reactivefluid/ReactiveFluidSelector.hpp | 51 +++ .../ReactiveSinglePhaseFluid.cpp | 77 ++-- .../ReactiveSinglePhaseFluid.hpp | 200 ++++++++--- .../fluid/singlefluid/SingleFluidSelector.hpp | 10 +- .../ReactiveCompressibleSinglePhaseFluid.cpp | 163 --------- .../ReactiveCompressibleSinglePhaseFluid.hpp | 291 --------------- .../reactive/ReactiveSingleFluid.cpp | 105 ------ .../reactive/ReactiveSingleFluid.hpp | 238 ------------- ...alReactiveCompressibleSinglePhaseFluid.cpp | 128 ------- ...alReactiveCompressibleSinglePhaseFluid.hpp | 333 ------------------ .../physicsSolvers/fluidFlow/CMakeLists.txt | 1 + .../SinglePhaseReactiveTransport.cpp | 50 ++- .../SinglePhaseReactiveTransport.hpp | 5 +- .../singlePhase/ReactiveFluidUpdateKernel.hpp | 59 ---- .../reactive/AccumulationKernels.hpp | 12 +- .../reactive/FluidUpdateKernel.hpp | 2 - .../reactive/FluxComputeKernel.hpp | 6 +- .../reactive/ReactionUpdateKernel.hpp | 79 +++++ .../reactive/ThermalAccumulationKernels.hpp | 4 +- .../reactive/ThermalFluxComputeKernel.hpp | 2 +- 21 files changed, 383 insertions(+), 1440 deletions(-) create mode 100644 src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidSelector.hpp delete mode 100644 src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.cpp delete mode 100644 src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp delete mode 100644 src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.cpp delete mode 100644 src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp delete mode 100644 src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.cpp delete mode 100644 src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp delete mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ReactiveFluidUpdateKernel.hpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index 31e486381b9..c9039356a80 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -120,6 +120,7 @@ set( constitutive_headers fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp fluid/reactivefluid/ReactiveFluidFields.hpp fluid/reactivefluid/ReactiveFluidLayouts.hpp + fluid/reactivefluid/ReactiveFluidSelector.hpp fluid/singlefluid/CompressibleSinglePhaseFluid.hpp fluid/singlefluid/ParticleFluid.hpp fluid/singlefluid/ParticleFluidBase.hpp @@ -132,9 +133,6 @@ set( constitutive_headers fluid/singlefluid/SingleFluidSelector.hpp fluid/singlefluid/SlurryFluidSelector.hpp fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp - fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp - fluid/singlefluid/reactive/ReactiveSingleFluid.hpp - fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp permeability/CarmanKozenyPermeability.hpp permeability/ConstantPermeability.hpp permeability/DamagePermeability.hpp @@ -275,9 +273,6 @@ set( constitutive_sources fluid/singlefluid/SingleFluidBase.cpp fluid/singlefluid/SlurryFluidBase.cpp fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.cpp - fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.cpp - fluid/singlefluid/reactive/ReactiveSingleFluid.cpp - fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.cpp permeability/CarmanKozenyPermeability.cpp permeability/ConstantPermeability.cpp permeability/DamagePermeability.cpp diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidSelector.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidSelector.hpp new file mode 100644 index 00000000000..8a3ef4b4602 --- /dev/null +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidSelector.hpp @@ -0,0 +1,51 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactiveFluidSelector.hpp + */ +#ifndef GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUID_REACTIVEFLUIDSELECTOR_HPP_ +#define GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUID_REACTIVEFLUIDSELECTOR_HPP_ + +#include "constitutive/ConstitutivePassThruHandler.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp" + +namespace geos +{ + +namespace constitutive +{ + +template< typename LAMBDA > +void constitutiveUpdatePassThru( SingleFluidBase const & fluid, + LAMBDA && lambda ) +{ + ConstitutivePassThruHandler< reactivefluid::ReactiveCompressibleSinglePhaseFluid, + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >::execute( fluid, std::forward< LAMBDA >( lambda ) ); +} + +template< typename LAMBDA > +void constitutiveUpdatePassThru( SingleFluidBase & fluid, + LAMBDA && lambda ) +{ + ConstitutivePassThruHandler< reactivefluid::ReactiveCompressibleSinglePhaseFluid, + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >::execute( fluid, std::forward< LAMBDA >( lambda ) ); +} + +} // namespace constitutive + +} // namespace geos + +#endif //GEOS_CONSTITUTIVE_FLUID_REACTIVEFLUID_REACTIVEFLUIDSELECTOR_HPP_ diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index cb0f8cfb896..b8e30726198 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -30,77 +30,86 @@ namespace constitutive namespace reactivefluid { -using namespace hpcReact::bulkGeneric; +using namespace hpcReact::bulkGeneric; template< typename BASE > ReactiveSinglePhaseFluid< BASE >:: - ReactiveSinglePhaseFluid( string const & name, Group * const parent ) : +ReactiveSinglePhaseFluid( string const & name, Group * const parent ): BASE( name, parent ) { - registerWrapper( viewKeyStruct::chemicalSystemNameString(), &m_chemicalSystemType ). - setInputFlag( InputFlags::REQUIRED ). - setDescription( "Chemical System type. Available options are: " - "``" + EnumStrings< ChemicalSystemType >::concat( "|" ) + "``" ); + this->registerWrapper( viewKeyStruct::chemicalSystemNameString(), &m_chemicalSystemType ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Chemical System type. Available options are: " + "``" + EnumStrings< ChemicalSystemType >::concat( "|" ) + "``" ); // For now this is being hardcoded. We will see where this should come from. - m_numPrimarySpecies = 7; + m_numPrimarySpecies = 5; m_numSecondarySpecies = 11; - registerField( fields::reactivefluid::primarySpeciesConcentration{}, &m_primarySpeciesConcentration ); - registerField( fields::reactivefluid::secondarySpeciesConcentration{}, &m_secondarySpeciesConcentration ); - registerField( fields::reactivefluid::primarySpeciesTotalConcentration{}, &m_primarySpeciesTotalConcentration ); + this->registerField( fields::reactivefluid::primarySpeciesConcentration{}, &m_primarySpeciesConcentration ); + this->registerField( fields::reactivefluid::secondarySpeciesConcentration{}, &m_secondarySpeciesConcentration ); + this->registerField( fields::reactivefluid::primarySpeciesAggregateConcentration{}, &m_primarySpeciesAggregateConcentration ); + this->registerField( fields::reactivefluid::primarySpeciesAggregateConcentration_n{}, &m_primarySpeciesAggregateConcentration_n ); + this->registerField( fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimaryConc{}, &m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc ); } template< typename BASE > std::unique_ptr< ConstitutiveBase > ReactiveSinglePhaseFluid< BASE >:: - deliverClone( string const & name, Group * const parent ) const +deliverClone( string const & name, Group * const parent ) const { std::unique_ptr< ConstitutiveBase > clone = BASE::deliverClone( name, parent ); ReactiveSinglePhaseFluid & newConstitutiveRelation = dynamicCast< ReactiveSinglePhaseFluid & >( *clone ); + GEOS_UNUSED_VAR( newConstitutiveRelation ); + return clone; } template< typename BASE > void ReactiveSinglePhaseFluid< BASE >::postInputInitialization() -{} +{ + BASE::postInputInitialization(); +} template< typename BASE > -void ReactiveSinglePhaseFluid< BASE >::resizeFields( localIndex const size, localIndex const numPts ) +void ReactiveSinglePhaseFluid< BASE >::saveConvergedState() const { - BASE::resizeFields( size, numPts ); + BASE::saveConvergedState(); + m_primarySpeciesAggregateConcentration_n.setValues< parallelDevicePolicy<> >( m_primarySpeciesAggregateConcentration.toViewConst() ); +} + +template< typename BASE > +void ReactiveSinglePhaseFluid< BASE >::resizeFields( localIndex const size, localIndex const numPts ) +{ + GEOS_UNUSED_VAR( numPts ); integer const numPrimarySpecies = this->numPrimarySpecies(); integer const numSecondarySpecies = this->numSecondarySpecies(); - + m_primarySpeciesConcentration.resize( size, numPrimarySpecies ); m_secondarySpeciesConcentration.resize( size, numSecondarySpecies ); - m_primarySpeciesTotalConcentration.resize( size, numPrimarySpecies ); + m_primarySpeciesAggregateConcentration.resize( size, numPrimarySpecies ); + m_primarySpeciesAggregateConcentration_n.resize( size, numPrimarySpecies ); + m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc.resize( size, numPrimarySpecies, numPrimarySpecies ); } template< typename BASE > -std::variant< KernelWrapper< carbonateSystemType >, - KernelWrapper< simpleTestType > > -ReactiveSinglePhaseFluid< BASE >createKernelWrapper() const +void ReactiveSinglePhaseFluid< BASE >::allocateConstitutiveData( dataRepository::Group & parent, + localIndex const numConstitutivePointsPerParentIndex ) { - switch ( m_chemicalSystemType ) - { - case ChemicalSystemType::carbonates: - return KernelWrapper< hpcReact::bubulkGeneric::carbonateSystemType >( m_primarySpeciesConcentration, - m_secondarySpeciesConcentration, - m_primarySpeciesTotalConcentration, - m_numSecondarySpecies, - carbonateSystem ); - default: - return KernelWrapper< hpcReact::bubulkGeneric::simpleTestType >( m_primarySpeciesConcentration, - m_secondarySpeciesConcentration, - m_primarySpeciesTotalConcentration, - m_numSecondarySpecies, - simpleTest ); - } + BASE::allocateConstitutiveData( parent, numConstitutivePointsPerParentIndex ); + resizeFields( parent.size(), numConstitutivePointsPerParentIndex ); } +template class ReactiveSinglePhaseFluid< CompressibleSinglePhaseFluid >; + +REGISTER_CATALOG_ENTRY( ConstitutiveBase, ReactiveCompressibleSinglePhaseFluid, string const &, Group * const ) + +template class ReactiveSinglePhaseFluid< ThermalCompressibleSinglePhaseFluid >; + +REGISTER_CATALOG_ENTRY( ConstitutiveBase, ReactiveThermalCompressibleSinglePhaseFluid, string const &, Group * const ) + } // namespace reactivefluid } // namespace constitutive diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index 03117773612..8294562b0ea 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -24,9 +24,12 @@ #include "constitutive/ConstitutiveBase.hpp" #include "constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp" +#include "constitutive/fluid/singlefluid/CompressibleSinglePhaseFluid.hpp" +#include "constitutive/fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp" #include "constitutive/HPCReact/src/reactions/bulkGeneric/ParametersPredefined.hpp" #include "constitutive/HPCReact/src/reactions/bulkGeneric/EquilibriumReactions.hpp" +#include "constitutive/HPCReact/src/reactions/bulkGeneric/SpeciesUtilities.hpp" #include namespace geos @@ -34,14 +37,17 @@ namespace geos namespace constitutive { - + namespace reactivefluid { +using namespace hpcReact::bulkGeneric; + enum class ChemicalSystemType : integer { carbonate, - ultramafic + ultramafic, + simple }; template< typename BASE > @@ -55,53 +61,85 @@ class ReactiveSinglePhaseFluid : public BASE virtual std::unique_ptr< ConstitutiveBase > deliverClone( string const & name, dataRepository::Group * const parent ) const override; + + static string catalogName() { return string( "Reactive" ) + BASE::catalogName(); } + virtual string getCatalogName() const override { return catalogName(); } + + virtual void saveConvergedState() const override; + + virtual void allocateConstitutiveData( dataRepository::Group & parent, + localIndex const numConstitutivePointsPerParentIndex ) override; - virtual bool isThermal() const override; + // virtual bool isThermal() const override; - arrayView2d< real64 const, compflow::USD_COMP > primarySpeciesConcentration() const + arrayView2d< real64 const, reactivefluid::USD_COMP > primarySpeciesConcentration() const { return m_primarySpeciesConcentration; } - arrayView2d< real64 const, compflow::USD_COMP > secondarySpeciesConcentration() const + arrayView2d< real64 const, reactivefluid::USD_COMP > primarySpeciesAggregateConcentration() const + { return m_primarySpeciesAggregateConcentration; } + + arrayView2d< real64 const, reactivefluid::USD_COMP > primarySpeciesAggregateConcentration_n() const + { return m_primarySpeciesAggregateConcentration_n; } + + arrayView3d< real64 const, reactivefluid::USD_COMP_DC > dPrimarySpeciesAggregateConcentration_dLogPrimaryConc() const + { return m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; } + + arrayView2d< real64 const, reactivefluid::USD_COMP > secondarySpeciesConcentration() const { return m_secondarySpeciesConcentration; } integer numPrimarySpecies() const { return m_numPrimarySpecies; } integer numSecondarySpecies() const { return m_numSecondarySpecies; } - auto createKernelWraper() const - { - - - std::variant< KernelWrapper< hpcReact::bubulkGeneric::carbonateSystemType >, - KernelWrapper< hpcReact::bubulkGeneric::simpleTestType > > - createKernelWrapper() const; - /** * @brief Kernel wrapper class for ReactiveSinglePhaseFluid. */ template< typename REACTION_PARAMS_TYPE > - class KernelWrapper : public BASE::KernelWrapper + class ReactionKernelWrapper { public: - KernelWrapper( arrayView2d< real64, reactivefluid::USD_COMP > const & secondarySpeciesConcentration, - integer const numPrimarySpecies, - integer const numSecondarySpecies, - REACTION_PARAMS_TYPE params ) : - m_secondarySpeciesConcentration( secondarySpeciesConcentration ), + ReactionKernelWrapper( arrayView2d< real64, reactivefluid::USD_COMP > const & primarySpeciesConcentration, + arrayView2d< real64, reactivefluid::USD_COMP > const & primarySpeciesAggregateConcentration, + arrayView2d< real64, reactivefluid::USD_COMP > const & secondarySpeciesConcentration, + integer const numPrimarySpecies, + integer const numSecondarySpecies, + REACTION_PARAMS_TYPE params ): m_numPrimarySpecies( numPrimarySpecies ), m_numSecondarySpecies( numSecondarySpecies ), + m_primarySpeciesConcentration( primarySpeciesConcentration ), + m_primarySpeciesAggregateConcentration( primarySpeciesAggregateConcentration ), + m_secondarySpeciesConcentration( secondarySpeciesConcentration ), m_params( params ) {} using EquilibriumReactionsType = hpcReact::bulkGeneric::EquilibriumReactions< real64, integer, localIndex >; - void computeChemistry( real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, reactivefluid::USD_COMP - 1 > const & primarySpeciesTotalConcentration, - arraySlice1d< real64, reactivefluid::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, reactivefluid::USD_COMP - 1 > const & secondarySpeciesConcentration ) const; + /** + * @brief Get number of elements in this wrapper. + * @return number of elements + */ + GEOS_HOST_DEVICE + localIndex numElems() const { return m_secondarySpeciesConcentration.size( 0 ); } + + void updateEquilibriumReaction( localIndex const k, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, reactivefluid::USD_COMP - 1 > const & primarySpeciesTotalConcentration, + arraySlice1d< real64, reactivefluid::USD_COMP - 1 > const & logPrimarySpeciesConcentration ) const; + + void enforceEquilibrium( real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, reactivefluid::USD_COMP - 1 > const & primarySpeciesTotalConcentration, + arraySlice1d< real64, reactivefluid::USD_COMP - 1 > const & primarySpeciesConcentration, + arraySlice1d< real64, reactivefluid::USD_COMP - 1 > const & secondarySpeciesConcentration ) const; + + void computeReactionRates( real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, reactivefluid::USD_COMP - 1 > const & primarySpeciesTotalConcentration, + arraySlice1d< real64, reactivefluid::USD_COMP - 1 > const & primarySpeciesConcentration, + arraySlice1d< real64, reactivefluid::USD_COMP - 1 > const & secondarySpeciesConcentration ) const; protected: @@ -109,6 +147,10 @@ class ReactiveSinglePhaseFluid : public BASE integer m_numSecondarySpecies; + arrayView2d< real64, reactivefluid::USD_COMP > m_primarySpeciesConcentration; + + arrayView2d< real64, reactivefluid::USD_COMP > m_primarySpeciesAggregateConcentration; + arrayView2d< real64, reactivefluid::USD_COMP > m_secondarySpeciesConcentration; arrayView2d< real64, reactivefluid::USD_COMP > m_kineticReactionRates; @@ -116,6 +158,30 @@ class ReactiveSinglePhaseFluid : public BASE REACTION_PARAMS_TYPE m_params; }; + std::variant< + typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemType >, + typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::simpleTestType > > + createReactionKernelWrapper() const + { + switch( m_chemicalSystemType ) + { + case ChemicalSystemType::carbonate: + return ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemType >( m_primarySpeciesConcentration, + m_primarySpeciesAggregateConcentration, + m_secondarySpeciesConcentration, + m_numPrimarySpecies, + m_numSecondarySpecies, + carbonateSystem ); + default: + return ReactionKernelWrapper< hpcReact::bulkGeneric::simpleTestType >( m_primarySpeciesConcentration, + m_primarySpeciesAggregateConcentration, + m_secondarySpeciesConcentration, + m_numPrimarySpecies, + m_numSecondarySpecies, + simpleTestRateParams ); + } + } + struct viewKeyStruct : ConstitutiveBase::viewKeyStruct { static constexpr char const * chemicalSystemNameString() { return "chemicalSystemType"; } @@ -125,54 +191,94 @@ class ReactiveSinglePhaseFluid : public BASE virtual void postInputInitialization() override; - virtual void resizeFields( localIndex const size, localIndex const numPts ) override; + virtual void resizeFields( localIndex const size, localIndex const numPts ); integer m_numPrimarySpecies; - + integer m_numSecondarySpecies; + array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_primarySpeciesConcentration; + array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_secondarySpeciesConcentration; + array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_primarySpeciesAggregateConcentration; + + array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_primarySpeciesAggregateConcentration_n; + + array3d< real64, constitutive::reactivefluid::LAYOUT_FLUID_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; + array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_kineticReactionRates; ChemicalSystemType m_chemicalSystemType; }; +// these aliases are useful in constitutive dispatch +using ReactiveSinglePhaseFluidBase = ReactiveSinglePhaseFluid< SingleFluidBase >; + +using ReactiveCompressibleSinglePhaseFluid = ReactiveSinglePhaseFluid< CompressibleSinglePhaseFluid >; + +using ReactiveThermalCompressibleSinglePhaseFluid = ReactiveSinglePhaseFluid< ThermalCompressibleSinglePhaseFluid >; + template< typename BASE > +template< typename REACTION_PARAMS_TYPE > inline void -ReactiveSinglePhaseFluid< BASE >::KernelWrapper:: - enforceEquilibrium( real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration ) const +ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >:: +updateEquilibriumReaction( localIndex const k, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration ) const { - GEOS_UNUSED_VAR( pressure ); - // 1. We enforce equilibrium - EquilibriumReactionsType::enforceEquilibrium_Extents( temperature, m_params, primarySpeciesAggregateConcentration, primarySpeciesConcentration ); - // 2. We calculate the secondary species concentration - speciesUtilities::calculateLogSecondarySpeciesConcentration( m_params, primarySpeciesConcentration, secondarySpeciesConcentration ); + enforceEquilibrium( pressure, temperature, primarySpeciesAggregateConcentration, m_primarySpeciesConcentration[k], m_secondarySpeciesConcentration[k] ); + + for( int i=0; i < m_numPrimarySpecies; i++ ) + { + real64 const primarySpeciesConc_i = m_primarySpeciesConcentration[k][i]; + + logPrimarySpeciesConcentration[i] = LvArray::math::log( primarySpeciesConc_i ); + } } template< typename BASE > +template< typename REACTION_PARAMS_TYPE > inline void -ReactiveSinglePhaseFluid< BASE >::KernelWrapper:: - computeReactionRates( real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration ) const +ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >:: +enforceEquilibrium( real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration ) const +{ + GEOS_UNUSED_VAR( pressure, temperature, secondarySpeciesConcentration ); + // 1. We enforce equilibrium + EquilibriumReactionsType::enforceEquilibrium_Extents( 298.15, m_params, primarySpeciesAggregateConcentration, primarySpeciesConcentration ); + // // 2. We calculate the secondary species concentration + // hpcReact::bulkGeneric::calculateLogSecondarySpeciesConcentration< real64, + // localIndex, + // localIndex >( m_params, primarySpeciesConcentration, secondarySpeciesConcentration ); +} + +template< typename BASE > +template< typename REACTION_PARAMS_TYPE > +inline void +ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >:: +computeReactionRates( real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration ) const { GEOS_UNUSED_VAR( pressure ); - // 1. We enforce equilibrium + // 1. We enforce equilibrium EquilibriumReactionsType::enforceEquilibrium_Extents( temperature, m_params, primarySpeciesAggregateConcentration, primarySpeciesConcentration ); - // 2. We calculate the secondary species concentration - speciesUtilities::calculateLogSecondarySpeciesConcentration( m_params, primarySpeciesConcentration, secondarySpeciesConcentration ); + // 2. We calculate the secondary species concentration + hpcReact::bulkGeneric::utilities_impl::calculateLogSecondarySpeciesConcentration( m_params, primarySpeciesConcentration, secondarySpeciesConcentration ); } ENUM_STRINGS( ChemicalSystemType, "carbonate", - "ultramafic" ); + "ultramafic", + "simple" ); } // namespace reactivefluid diff --git a/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidSelector.hpp b/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidSelector.hpp index ba378a397e1..be6560c6c21 100644 --- a/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidSelector.hpp +++ b/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidSelector.hpp @@ -22,8 +22,6 @@ #include "constitutive/ConstitutivePassThruHandler.hpp" #include "constitutive/fluid/singlefluid/CompressibleSinglePhaseFluid.hpp" #include "constitutive/fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp" -#include "constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp" -#include "constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp" namespace geos { @@ -35,9 +33,7 @@ template< typename LAMBDA > void constitutiveUpdatePassThru( SingleFluidBase const & fluid, LAMBDA && lambda ) { - ConstitutivePassThruHandler< ThermalReactiveCompressibleSinglePhase, - ReactiveCompressibleSinglePhase, - ThermalCompressibleSinglePhaseFluid, + ConstitutivePassThruHandler< ThermalCompressibleSinglePhaseFluid, CompressibleSinglePhaseFluid >::execute( fluid, std::forward< LAMBDA >( lambda ) ); } @@ -45,9 +41,7 @@ template< typename LAMBDA > void constitutiveUpdatePassThru( SingleFluidBase & fluid, LAMBDA && lambda ) { - ConstitutivePassThruHandler< ThermalReactiveCompressibleSinglePhase, - ReactiveCompressibleSinglePhase, - ThermalCompressibleSinglePhaseFluid, + ConstitutivePassThruHandler< ThermalCompressibleSinglePhaseFluid, CompressibleSinglePhaseFluid >::execute( fluid, std::forward< LAMBDA >( lambda ) ); } diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.cpp deleted file mode 100644 index c5af8c0fe0d..00000000000 --- a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.cpp +++ /dev/null @@ -1,163 +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 ReactiveCompressibleSinglePhaseFluid.cpp - */ - -#include "ReactiveCompressibleSinglePhaseFluid.hpp" - -#include "constitutive/fluid/singlefluid/SingleFluidFields.hpp" - -namespace geos -{ - -using namespace dataRepository; - -namespace constitutive -{ - -ReactiveCompressibleSinglePhase::ReactiveCompressibleSinglePhase( string const & name, Group * const parent ): - ReactiveSingleFluid( name, parent ), - m_densityModelType( ExponentApproximationType::Linear ), - m_viscosityModelType( ExponentApproximationType::Linear ) -{ - registerWrapper( viewKeyStruct::defaultDensityString(), &m_defaultDensity ). - setInputFlag( InputFlags::REQUIRED ). - setDescription( "Default value for density." ); - - registerWrapper( viewKeyStruct::defaultViscosityString(), &m_defaultViscosity ). - setInputFlag( InputFlags::REQUIRED ). - setDescription( "Default value for viscosity." ); - - registerWrapper( viewKeyStruct::compressibilityString(), &m_compressibility ). - setApplyDefaultValue( 0.0 ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Fluid compressibility" ); - - registerWrapper( viewKeyStruct::viscosibilityString(), &m_viscosibility ). - setApplyDefaultValue( 0.0 ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Fluid viscosity exponential coefficient" ); - - registerWrapper( viewKeyStruct::referencePressureString(), &m_referencePressure ). - setApplyDefaultValue( 0.0 ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Reference pressure" ); - - registerWrapper( viewKeyStruct::referenceDensityString(), &m_referenceDensity ). - setApplyDefaultValue( 1000.0 ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Reference fluid density" ); - - registerWrapper( viewKeyStruct::referenceViscosityString(), &m_referenceViscosity ). - setApplyDefaultValue( 0.001 ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Reference fluid viscosity" ); - - registerWrapper( viewKeyStruct::densityModelTypeString(), &m_densityModelType ). - setApplyDefaultValue( m_densityModelType ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Type of density model. Valid options:\n* " + EnumStrings< ExponentApproximationType >::concat( "\n* " ) ); - - registerWrapper( viewKeyStruct::viscosityModelTypeString(), &m_viscosityModelType ). - setApplyDefaultValue( m_viscosityModelType ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Type of viscosity model. Valid options:\n* " + EnumStrings< ExponentApproximationType >::concat( "\n* " ) ); - -} - -ReactiveCompressibleSinglePhase::~ReactiveCompressibleSinglePhase() = default; - -void ReactiveCompressibleSinglePhase::allocateConstitutiveData( dataRepository::Group & parent, - localIndex const numConstitutivePointsPerParentIndex ) -{ - ReactiveSingleFluid::allocateConstitutiveData( parent, numConstitutivePointsPerParentIndex ); - - getField< fields::singlefluid::density >().setApplyDefaultValue( m_defaultDensity ); - getField< fields::singlefluid::viscosity >().setApplyDefaultValue( m_defaultViscosity ); - - m_density.value.setValues< serialPolicy >( m_referenceDensity ); - m_viscosity.value.setValues< serialPolicy >( m_referenceViscosity ); -} - -void ReactiveCompressibleSinglePhase::postInputInitialization() -{ - ReactiveSingleFluid::postInputInitialization(); - - auto const checkNonnegative = [&]( real64 const value, auto const & attribute ) - { - GEOS_THROW_IF_LT_MSG( value, 0.0, - GEOS_FMT( "{}: invalid value of attribute '{}'", getFullName(), attribute ), - InputError ); - }; - checkNonnegative( m_compressibility, viewKeyStruct::compressibilityString() ); - checkNonnegative( m_viscosibility, viewKeyStruct::viscosibilityString() ); - - auto const checkPositive = [&]( real64 const value, auto const & attribute ) - { - GEOS_THROW_IF_LE_MSG( value, 0.0, - GEOS_FMT( "{}: invalid value of attribute '{}'", getFullName(), attribute ), - InputError ); - }; - checkPositive( m_referenceDensity, viewKeyStruct::referenceDensityString() ); - checkPositive( m_referenceViscosity, viewKeyStruct::referenceViscosityString() ); - - // Due to the way update wrapper is currently implemented, we can only support one model type - auto const checkModelType = [&]( ExponentApproximationType const value, auto const & attribute ) - { - GEOS_THROW_IF_NE_MSG( value, ExponentApproximationType::Linear, - GEOS_FMT( "{}: invalid model type in attribute '{}' (only linear currently supported)", getFullName(), attribute ), - InputError ); - }; - checkModelType( m_densityModelType, viewKeyStruct::densityModelTypeString() ); - checkModelType( m_viscosityModelType, viewKeyStruct::viscosityModelTypeString() ); - - // Set default values for derivatives (cannot be done in base class) - // TODO: reconsider the necessity of this - - real64 dRho_dP; - real64 dVisc_dP; - createKernelWrapper().compute( m_referencePressure, m_referenceDensity, dRho_dP, m_referenceViscosity, dVisc_dP ); - for( integer i=0; i - -namespace geos -{ - -namespace constitutive -{ - -/** - * @brief Update class for the model suitable for lambda capture. - * @tparam DENS_EAT type of density exponent approximation - * @tparam VISC_EAT type of viscosity exponent approximation - */ -template< ExponentApproximationType DENS_EAT, ExponentApproximationType VISC_EAT > -class ReactiveCompressibleSinglePhaseUpdate : public ReactiveSingleFluidUpdate -{ -public: - - using DensRelationType = ExponentialRelation< real64, DENS_EAT >; - using ViscRelationType = ExponentialRelation< real64, VISC_EAT >; - using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; - - ReactiveCompressibleSinglePhaseUpdate( DensRelationType const & densRelation, - ViscRelationType const & viscRelation, - arrayView2d< real64, constitutive::singlefluid::USD_FLUID > const & density, - arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > const & dDensity, - arrayView2d< real64, constitutive::singlefluid::USD_FLUID > const & viscosity, - arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > const & dViscosity, - integer const numPrimarySpecies, - // chemicalReactions::EquilibriumReactions const & equilibriumReactions, - // chemicalReactions::KineticReactions const & kineticReactions, - arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesConcentration, - arrayView2d< real64, compflow::USD_COMP > const & secondarySpeciesConcentration, - arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesAggregateConcentration, - arrayView3d< real64, compflow::USD_COMP_DC > const & dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, - arrayView2d< real64, compflow::USD_COMP > const & kineticReactionRates ) - : ReactiveSingleFluidUpdate( density, dDensity, viscosity, dViscosity, numPrimarySpecies, - // equilibriumReactions, kineticReactions, - primarySpeciesConcentration, secondarySpeciesConcentration, primarySpeciesAggregateConcentration, - dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, kineticReactionRates ), - m_densRelation( densRelation ), - m_viscRelation( viscRelation ) - {} - - /// Default copy constructor - ReactiveCompressibleSinglePhaseUpdate( ReactiveCompressibleSinglePhaseUpdate const & ) = default; - - /// Default move constructor - ReactiveCompressibleSinglePhaseUpdate( ReactiveCompressibleSinglePhaseUpdate && ) = default; - - /// Deleted copy assignment operator - ReactiveCompressibleSinglePhaseUpdate & operator=( ReactiveCompressibleSinglePhaseUpdate const & ) = delete; - - /// Deleted move assignment operator - ReactiveCompressibleSinglePhaseUpdate & operator=( ReactiveCompressibleSinglePhaseUpdate && ) = delete; - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void compute( real64 const pressure, - real64 & density, - real64 & dDensity_dPressure, - real64 & viscosity, - real64 & dViscosity_dPressure ) const override - { - m_densRelation.compute( pressure, density, dDensity_dPressure ); - m_viscRelation.compute( pressure, viscosity, dViscosity_dPressure ); - } - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void compute( real64 const pressure, - real64 const GEOS_UNUSED_PARAM( temperature ), - real64 & density, - real64 & dDensity_dPressure, - real64 & GEOS_UNUSED_PARAM( dDensity_dTemperature ), - real64 & viscosity, - real64 & dViscosity_dPressure, - real64 & GEOS_UNUSED_PARAM( dViscosity_dTemperature ), - real64 & GEOS_UNUSED_PARAM( internalEnergy ), - real64 & GEOS_UNUSED_PARAM( dInternalEnergy_dPressure ), - real64 & GEOS_UNUSED_PARAM( dInternalEnergy_dTemperature ), - real64 & GEOS_UNUSED_PARAM( enthalpy ), - real64 & GEOS_UNUSED_PARAM( dEnthalpy_dPressure ), - real64 & GEOS_UNUSED_PARAM( dEnthalpy_dTemperature ) ) const override - { - m_densRelation.compute( pressure, density, dDensity_dPressure ); - m_viscRelation.compute( pressure, viscosity, dViscosity_dPressure ); - } - - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void update( localIndex const k, - localIndex const q, - real64 const pressure ) const override - { - compute( pressure, - m_density[k][q], - m_dDensity[k][q][DerivOffset::dP], - m_viscosity[k][q], - m_dViscosity[k][q][DerivOffset::dP] ); - } - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void update( localIndex const k, - localIndex const q, - real64 const pressure, - real64 const GEOS_UNUSED_PARAM( temperature ) ) const override - { - compute( pressure, - m_density[k][q], - m_dDensity[k][q][DerivOffset::dP], - m_viscosity[k][q], - m_dViscosity[k][q][DerivOffset::dP] ); - } - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void update( localIndex const k, - localIndex const q, - real64 const pressure, - real64 const GEOS_UNUSED_PARAM( temperature ), - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & GEOS_UNUSED_PARAM( logPrimaryConc ) ) const override - { - compute( pressure, - m_density[k][q], - m_dDensity[k][q][DerivOffset::dP], - m_viscosity[k][q], - m_dViscosity[k][q][DerivOffset::dP] ); - } - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void updateChemistry( localIndex const k, - localIndex const GEOS_UNUSED_PARAM( q ), - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primaryConc ) const override - { - for( int i=0; i < m_numPrimarySpecies; i++ ) - { - m_primarySpeciesAggregateConcentration[k][i] = primaryConc[i]; - } - - computeChemistry( pressure, - temperature, - m_primarySpeciesAggregateConcentration[k], - m_primarySpeciesConcentration[k], - m_secondarySpeciesConcentration[k], - m_kineticReactionRates[k] ); - } - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void updateChemistryLogConc( localIndex const k, - localIndex const GEOS_UNUSED_PARAM( q ), - real64 const GEOS_UNUSED_PARAM( pressure ), - real64 const GEOS_UNUSED_PARAM( temperature ), - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimaryConc ) const override - { - for( int i=0; i < m_numPrimarySpecies; i++ ) - { - m_primarySpeciesConcentration[k][i] = std::exp( logPrimaryConc[i] ); - - m_primarySpeciesAggregateConcentration[k][i] = m_primarySpeciesConcentration[k][i]; - - m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc[k][i][i] = m_primarySpeciesConcentration[k][i]; - } - - // computeChemistry( pressure, - // temperature, - // m_primarySpeciesAggregateConcentration[k], - // m_primarySpeciesConcentration[k], - // m_secondarySpeciesConcentration[k], - // m_kineticReactionRates[k] ); - } - -private: - - /// Relationship between the fluid density and pressure - DensRelationType m_densRelation; - - /// Relationship between the fluid viscosity and pressure - ViscRelationType m_viscRelation; - -}; - -class ReactiveCompressibleSinglePhase : public ReactiveSingleFluid -{ -public: - using DerivOffset = singlefluid::DerivativeOffset; - ReactiveCompressibleSinglePhase( string const & name, Group * const parent ); - - virtual ~ReactiveCompressibleSinglePhase() override; - - static string catalogName() { return "ReactiveCompressibleSinglePhase"; } - - virtual string getCatalogName() const override { return catalogName(); } - - virtual void allocateConstitutiveData( dataRepository::Group & parent, - localIndex const numConstitutivePointsPerParentIndex ) override; - - /// Type of kernel wrapper for in-kernel update (TODO: support multiple EAT, not just linear) - using KernelWrapper = ReactiveCompressibleSinglePhaseUpdate< ExponentApproximationType::Linear, ExponentApproximationType::Linear >; - - /** - * @brief Create an update kernel wrapper. - * @return the wrapper - */ - KernelWrapper createKernelWrapper(); - - struct viewKeyStruct - { - static constexpr char const * defaultDensityString() { return "defaultDensity"; } - static constexpr char const * defaultViscosityString() { return "defaultViscosity"; } - static constexpr char const * compressibilityString() { return "compressibility"; } - static constexpr char const * viscosibilityString() { return "viscosibility"; } - static constexpr char const * referencePressureString() { return "referencePressure"; } - static constexpr char const * referenceDensityString() { return "referenceDensity"; } - static constexpr char const * referenceViscosityString() { return "referenceViscosity"; } - static constexpr char const * densityModelTypeString() { return "densityModelType"; } - static constexpr char const * viscosityModelTypeString() { return "viscosityModelType"; } - }; - - real64 defaultDensity() const override final { return m_defaultDensity; } - real64 defaultViscosity() const override final { return m_defaultViscosity; } - -protected: - - virtual void postInputInitialization() override; - - /// default density value - real64 m_defaultDensity; - - /// default viscosity value - real64 m_defaultViscosity; - - /// scalar fluid bulk modulus parameter - real64 m_compressibility; - - /// scalar fluid viscosity exponential coefficient - real64 m_viscosibility; - - /// reference pressure parameter - real64 m_referencePressure; - - /// reference density parameter - real64 m_referenceDensity; - - /// reference viscosity parameter - real64 m_referenceViscosity; - - /// type of density model in terms of pressure - ExponentApproximationType m_densityModelType; - - /// type of viscosity model - ExponentApproximationType m_viscosityModelType; - -}; - -} /* namespace constitutive */ - -} /* namespace geos */ - -#endif /* GEOS_CONSTITUTIVE_FLUID_REACTIVECOMPRESSIBLESINGLEPHASEFLUID_HPP_ */ diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.cpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.cpp deleted file mode 100644 index f406cf3e3a4..00000000000 --- a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.cpp +++ /dev/null @@ -1,105 +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 ReactiveSingleFluid.cpp - */ -#include "ReactiveSingleFluid.hpp" - -#include "constitutive/fluid/singlefluid/SingleFluidFields.hpp" -#include "constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp" - - -namespace geos -{ - -using namespace dataRepository; - -namespace constitutive -{ - -ReactiveSingleFluid:: - ReactiveSingleFluid( string const & name, Group * const parent ): - SingleFluidBase( name, parent ) -{ - registerWrapper( viewKeyStruct::primarySpeciesNamesString(), &m_primarySpeciesNames ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "List of primary species names" ); - - // For now this is being hardcoded. We will see where this should come from. - m_numPrimarySpecies = 3; - m_numSecondarySpecies = 11; - m_numKineticReactions = 2; - - registerField( fields::reactivefluid::primarySpeciesConcentration{}, &m_primarySpeciesConcentration ); - registerField( fields::reactivefluid::secondarySpeciesConcentration{}, &m_secondarySpeciesConcentration ); - registerField( fields::reactivefluid::primarySpeciesAggregateConcentration{}, &m_primarySpeciesAggregateConcentration ); - registerField( fields::reactivefluid::primarySpeciesAggregateConcentration_n{}, &m_primarySpeciesAggregateConcentration_n ); - registerField( fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimaryConc{}, &m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc ); - registerField( fields::reactivefluid::kineticReactionRates{}, &m_kineticReactionRates ); -} - -void ReactiveSingleFluid::postInputInitialization() -{ - SingleFluidBase::postInputInitialization(); - - // // call to correctly set member array tertiary sizes on the 'main' material object - // resizeFields( 0, 0 ); - - // createChemicalReactions(); -} - -void ReactiveSingleFluid::saveConvergedState() const -{ - SingleFluidBase::saveConvergedState(); - - m_primarySpeciesAggregateConcentration_n.setValues< parallelDevicePolicy<> >( m_primarySpeciesAggregateConcentration.toViewConst() ); -} - -void ReactiveSingleFluid::resizeFields( localIndex const size, localIndex const numPts ) -{ - GEOS_UNUSED_VAR( numPts ); - - integer const numPrimarySpecies = this->numPrimarySpecies(); - integer const numSecondarySpecies = this->numSecondarySpecies(); - integer const numKineticReactions = this->numKineticReactions(); - - m_primarySpeciesConcentration.resize( size, numPrimarySpecies ); - m_secondarySpeciesConcentration.resize( size, numSecondarySpecies ); - m_primarySpeciesAggregateConcentration.resize( size, numPrimarySpecies ); - m_primarySpeciesAggregateConcentration_n.resize( size, numPrimarySpecies ); - m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc.resize( size, numPrimarySpecies, numPrimarySpecies ); - m_kineticReactionRates.resize( size, numKineticReactions ); -} - -void ReactiveSingleFluid::allocateConstitutiveData( dataRepository::Group & parent, - localIndex const numConstitutivePointsPerParentIndex ) -{ - SingleFluidBase::allocateConstitutiveData( parent, numConstitutivePointsPerParentIndex ); - resizeFields( parent.size(), numConstitutivePointsPerParentIndex ); -} - -// void ReactiveSingleFluid::createChemicalReactions() -// { -// // instantiate reactions objects -// m_equilibriumReactions = std::make_unique< chemicalReactions::EquilibriumReactions >( getName() + "_equilibriumReactions", -// m_numPrimarySpecies, m_numSecondarySpecies ); -// m_kineticReactions = std::make_unique< chemicalReactions::KineticReactions >( getName() + "_kineticReactions", m_numPrimarySpecies, -// m_numSecondarySpecies, m_numKineticReactions ); -// } - -} //namespace constitutive - -} //namespace geos diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp deleted file mode 100644 index 48a5457faba..00000000000 --- a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp +++ /dev/null @@ -1,238 +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 ReactiveSingleFluid.hpp - */ - -#ifndef GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_REACTIVE_REACTIVESINGLEFLUID_HPP_ -#define GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_REACTIVE_REACTIVESINGLEFLUID_HPP_ - - -#include "common/format/EnumStrings.hpp" -#include "constitutive/fluid/singlefluid/SingleFluidBase.hpp" -#include "constitutive/fluid/multifluid/reactive/chemicalReactions/EquilibriumReactions.hpp" -#include "constitutive/fluid/multifluid/reactive/chemicalReactions/KineticReactions.hpp" - -#include - -namespace geos -{ - -namespace constitutive -{ - -class ReactiveSingleFluidUpdate : public SingleFluidBaseUpdate -{ -public: - - GEOS_HOST_DEVICE - void computeChemistry( real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & kineticReactionRates ) const; - - GEOS_HOST_DEVICE - virtual void updateChemistry( localIndex const k, - localIndex const q, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primaryConc ) const = 0; - - GEOS_HOST_DEVICE - virtual void updateChemistryLogConc( localIndex const k, - localIndex const q, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimaryConc ) const = 0; - -protected: - - ReactiveSingleFluidUpdate( arrayView2d< real64, constitutive::singlefluid::USD_FLUID > const & density, - arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > const & dDensity, - arrayView2d< real64, constitutive::singlefluid::USD_FLUID > const & viscosity, - arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > const & dViscosity, - integer const numPrimarySpecies, - // chemicalReactions::EquilibriumReactions const & equilibriumReactions, - // chemicalReactions::KineticReactions const & kineticReactions, - arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesConcentration, - arrayView2d< real64, compflow::USD_COMP > const & secondarySpeciesConcentration, - arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesAggregateConcentration, - arrayView3d< real64, compflow::USD_COMP_DC > const & dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, - arrayView2d< real64, compflow::USD_COMP > const & kineticReactionRates ) - : SingleFluidBaseUpdate( density, - dDensity, - viscosity, - dViscosity ), - m_numPrimarySpecies( numPrimarySpecies ), - // m_equilibriumReactions( equilibriumReactions.createKernelWrapper() ), - // m_kineticReactions( kineticReactions.createKernelWrapper() ), - m_primarySpeciesConcentration( primarySpeciesConcentration ), - m_secondarySpeciesConcentration( secondarySpeciesConcentration ), - m_primarySpeciesAggregateConcentration( primarySpeciesAggregateConcentration ), - m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc( dPrimarySpeciesAggregateConcentration_dLogPrimaryConc ), - m_kineticReactionRates( kineticReactionRates ) - {} - - /** - * @brief Copy constructor. - */ - ReactiveSingleFluidUpdate( ReactiveSingleFluidUpdate const & ) = default; - - /** - * @brief Move constructor. - */ - ReactiveSingleFluidUpdate( ReactiveSingleFluidUpdate && ) = default; - - /** - * @brief Deleted copy assignment operator - * @return reference to this object - */ - ReactiveSingleFluidUpdate & operator=( ReactiveSingleFluidUpdate const & ) = delete; - - /** - * @brief Deleted move assignment operator - * @return reference to this object - */ - ReactiveSingleFluidUpdate & operator=( ReactiveSingleFluidUpdate && ) = delete; - - /// Reaction related terms - integer m_numPrimarySpecies; - - // chemicalReactions::EquilibriumReactions::KernelWrapper m_equilibriumReactions; - - // chemicalReactions::KineticReactions::KernelWrapper m_kineticReactions; - - arrayView2d< real64, compflow::USD_COMP > m_primarySpeciesConcentration; - - arrayView2d< real64, compflow::USD_COMP > m_secondarySpeciesConcentration; - - arrayView2d< real64, compflow::USD_COMP > m_primarySpeciesAggregateConcentration; - - arrayView3d< real64, compflow::USD_COMP_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; - - arrayView2d< real64, compflow::USD_COMP > m_kineticReactionRates; -}; - -class ReactiveSingleFluid : public SingleFluidBase -{ -public: - - using exec_policy = serialPolicy; - - ReactiveSingleFluid( string const & name, - Group * const parent ); - - virtual void saveConvergedState() const override; - - virtual void allocateConstitutiveData( dataRepository::Group & parent, - localIndex const numConstitutivePointsPerParentIndex ) override; - - arrayView2d< real64 const, compflow::USD_COMP > primarySpeciesConcentration() const - { return m_primarySpeciesConcentration; } - - arrayView2d< real64 const, compflow::USD_COMP > primarySpeciesAggregateConcentration() const - { return m_primarySpeciesAggregateConcentration; } - - arrayView2d< real64 const, compflow::USD_COMP > primarySpeciesAggregateConcentration_n() const - { return m_primarySpeciesAggregateConcentration_n; } - - arrayView3d< real64 const, compflow::USD_COMP_DC > dPrimarySpeciesAggregateConcentration_dLogPrimaryConc() const - { return m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; } - - arrayView2d< real64 const, compflow::USD_COMP > secondarySpeciesConcentration() const - { return m_secondarySpeciesConcentration; } - - arrayView2d< real64 const, compflow::USD_COMP > kineticReactionRates() const - { return m_kineticReactionRates; } - - integer numPrimarySpecies() const { return m_numPrimarySpecies; } - - integer numSecondarySpecies() const { return m_numSecondarySpecies; } - - integer numKineticReactions() const { return m_numKineticReactions; } - - - struct viewKeyStruct : ConstitutiveBase::viewKeyStruct - { - static constexpr char const * primarySpeciesNamesString() { return "primarySpeciesNames"; } - }; - -protected: - - virtual void postInputInitialization() override; - - void createChemicalReactions(); - - virtual void resizeFields( localIndex const size, localIndex const numPts ); - - /// Reaction related terms - array1d< string > m_primarySpeciesNames; - - integer m_numPrimarySpecies; - - integer m_numSecondarySpecies; - - integer m_numKineticReactions; - - // std::unique_ptr< chemicalReactions::EquilibriumReactions > m_equilibriumReactions; - - // std::unique_ptr< chemicalReactions::KineticReactions > m_kineticReactions; - - array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_primarySpeciesConcentration; - - array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_secondarySpeciesConcentration; - - array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_primarySpeciesAggregateConcentration; - - array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_primarySpeciesAggregateConcentration_n; - - array3d< real64, constitutive::multifluid::LAYOUT_FLUID_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; - - array2d< real64, constitutive::multifluid::LAYOUT_FLUID > m_kineticReactionRates; -}; - -GEOS_HOST_DEVICE -GEOS_FORCE_INLINE -void ReactiveSingleFluidUpdate:: - computeChemistry( real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primarySpeciesAggregateConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & secondarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & kineticReactionRates ) const -{ - GEOS_UNUSED_VAR( pressure, temperature, primarySpeciesAggregateConcentration, primarySpeciesConcentration, secondarySpeciesConcentration, kineticReactionRates ); - - // // 2. solve for equilibrium - // m_equilibriumReactions.updateConcentrations( temperature, - // primarySpeciesAggregateConcentration, - // primarySpeciesConcentration, - // secondarySpeciesConcentration ); - - // // 3. compute kinetic reaction rates - // m_kineticReactions.computeReactionRates( temperature, - // primarySpeciesConcentration, - // secondarySpeciesConcentration, - // kineticReactionRates ); -} - -} // namespace constitutive - -} // namespace geos - -#endif //GEOS_CONSTITUTIVE_FLUID_REACTIVEMULTIFLUID_HPP diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.cpp deleted file mode 100644 index 3f7a746cf72..00000000000 --- a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.cpp +++ /dev/null @@ -1,128 +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 ThermalReactiveCompressibleSinglePhaseFluid.cpp - */ - -#include "ThermalReactiveCompressibleSinglePhaseFluid.hpp" - -#include "constitutive/fluid/singlefluid/SingleFluidFields.hpp" - -namespace geos -{ - -using namespace dataRepository; - -namespace constitutive -{ - -ThermalReactiveCompressibleSinglePhase::ThermalReactiveCompressibleSinglePhase( string const & name, Group * const parent ): - ReactiveCompressibleSinglePhase( name, parent ), - m_internalEnergyModelType( ExponentApproximationType::Linear ) -{ - m_densityModelType = ExponentApproximationType::Full; - registerWrapper( viewKeyStruct::thermalExpansionCoeffString(), &m_thermalExpansionCoeff ). - setApplyDefaultValue( 0.0 ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Fluid thermal expansion coefficient. Unit: 1/K" ); - - registerWrapper( viewKeyStruct::specificHeatCapacityString(), &m_specificHeatCapacity ). - setApplyDefaultValue( 0.0 ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Fluid heat capacity. Unit: J/kg/K" ); - - registerWrapper( viewKeyStruct::referenceTemperatureString(), &m_referenceTemperature ). - setApplyDefaultValue( 0.0 ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Reference temperature" ); - - registerWrapper( viewKeyStruct::referenceInternalEnergyString(), &m_referenceInternalEnergy ). - setApplyDefaultValue( 0.001 ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Reference fluid internal energy" ); - - registerWrapper( viewKeyStruct::internalEnergyModelTypeString(), &m_internalEnergyModelType ). - setApplyDefaultValue( m_internalEnergyModelType ). - setInputFlag( InputFlags::OPTIONAL ). - setDescription( "Type of internal energy model. Valid options:\n* " + EnumStrings< ExponentApproximationType >::concat( "\n* " ) ); - -} - -ThermalReactiveCompressibleSinglePhase::~ThermalReactiveCompressibleSinglePhase() = default; - -void ThermalReactiveCompressibleSinglePhase::allocateConstitutiveData( dataRepository::Group & parent, - localIndex const numConstitutivePointsPerParentIndex ) -{ - ReactiveCompressibleSinglePhase::allocateConstitutiveData( parent, numConstitutivePointsPerParentIndex ); - - m_internalEnergy.value.setValues< serialPolicy >( m_referenceInternalEnergy ); -} - -void ThermalReactiveCompressibleSinglePhase::postInputInitialization() -{ - ReactiveCompressibleSinglePhase::postInputInitialization(); - - auto const checkNonnegative = [&]( real64 const value, auto const & attribute ) - { - GEOS_THROW_IF_LT_MSG( value, 0.0, - GEOS_FMT( "{}: invalid value of attribute '{}'", getFullName(), attribute ), - InputError ); - }; - - checkNonnegative( m_thermalExpansionCoeff, viewKeyStruct::thermalExpansionCoeffString() ); - checkNonnegative( m_specificHeatCapacity, viewKeyStruct::specificHeatCapacityString() ); - checkNonnegative( m_referenceInternalEnergy, viewKeyStruct::referenceInternalEnergyString() ); - - // Due to the way update wrapper is currently implemented, we can only support one model type - auto const checkModelType = [&]( ExponentApproximationType const value, auto const & attribute ) - { - GEOS_THROW_IF( value != ExponentApproximationType::Linear && value != ExponentApproximationType::Full, - GEOS_FMT( "{}: invalid model type in attribute '{}' (only linear or fully exponential currently supported)", getFullName(), attribute ), - InputError ); - }; - checkModelType( m_internalEnergyModelType, viewKeyStruct::internalEnergyModelTypeString() ); -} - -ThermalReactiveCompressibleSinglePhase::KernelWrapper -ThermalReactiveCompressibleSinglePhase::createKernelWrapper() -{ - return KernelWrapper( KernelWrapper::DensRelationType( m_referencePressure, m_referenceTemperature, m_referenceDensity, m_compressibility, -m_thermalExpansionCoeff ), - KernelWrapper::ViscRelationType( m_referencePressure, m_referenceViscosity, m_viscosibility ), - KernelWrapper::IntEnergyRelationType( m_referenceTemperature, m_referenceInternalEnergy, m_specificHeatCapacity/m_referenceInternalEnergy ), - m_density.value, - m_density.derivs, - m_viscosity.value, - m_viscosity.derivs, - m_numPrimarySpecies, - // *m_equilibriumReactions, - // *m_kineticReactions, - m_primarySpeciesConcentration.toView(), - m_secondarySpeciesConcentration.toView(), - m_primarySpeciesAggregateConcentration.toView(), - m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc.toView(), - m_kineticReactionRates.toView(), - m_internalEnergy.value, - m_internalEnergy.derivs, - m_enthalpy.value, - m_enthalpy.derivs, - m_referenceInternalEnergy ); -} - -REGISTER_CATALOG_ENTRY( ConstitutiveBase, ThermalReactiveCompressibleSinglePhase, string const &, Group * const ) - -} /* namespace constitutive */ - -} /* namespace geos */ diff --git a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp deleted file mode 100644 index 8e0cdbdcfb1..00000000000 --- a/src/coreComponents/constitutive/fluid/singlefluid/reactive/ThermalReactiveCompressibleSinglePhaseFluid.hpp +++ /dev/null @@ -1,333 +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 ThermalReactiveCompressibleSinglePhaseFluid.hpp - */ - -#ifndef GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_THERMALREACTIVECOMPRESSIBLESINGLEPHASEFLUID_HPP_ -#define GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_THERMALREACTIVECOMPRESSIBLESINGLEPHASEFLUID_HPP_ - -#include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" -#include "constitutive/fluid/singlefluid/reactive/ReactiveCompressibleSinglePhaseFluid.hpp" - -#include "constitutive/ExponentialRelation.hpp" - -namespace geos -{ - -namespace constitutive -{ - -/** - * @brief Update class for the model suitable for lambda capture. - * @tparam DENS_EAT type of density exponent approximation for the pressure part - * @tparam VISC_EAT type of viscosity exponent approximation - * @tparam INTENERGY_EAT type of internal energy exponent approximation - */ -template< ExponentApproximationType DENS_EAT, ExponentApproximationType VISC_EAT, ExponentApproximationType INTENERGY_EAT > -class ThermalReactiveCompressibleSinglePhaseUpdate : public ReactiveSingleFluidUpdate -{ -public: - - using DensRelationType = ExponentialRelation< real64, DENS_EAT, 3 >; - using ViscRelationType = ExponentialRelation< real64, VISC_EAT >; - using IntEnergyRelationType = ExponentialRelation< real64, INTENERGY_EAT >; - using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; - - ThermalReactiveCompressibleSinglePhaseUpdate( DensRelationType const & densRelation, - ViscRelationType const & viscRelation, - IntEnergyRelationType const & intEnergyRelation, - arrayView2d< real64, constitutive::singlefluid::USD_FLUID > const & density, - arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > const & dDensity, - arrayView2d< real64, constitutive::singlefluid::USD_FLUID > const & viscosity, - arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > const & dViscosity, - integer const numPrimarySpecies, - // chemicalReactions::EquilibriumReactions const & equilibriumReactions, - // chemicalReactions::KineticReactions const & kineticReactions, - arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesConcentration, - arrayView2d< real64, compflow::USD_COMP > const & secondarySpeciesConcentration, - arrayView2d< real64, compflow::USD_COMP > const & primarySpeciesAggregateConcentration, - arrayView3d< real64, compflow::USD_COMP_DC > const & dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, - arrayView2d< real64, compflow::USD_COMP > const & kineticReactionRates, - arrayView2d< real64, constitutive::singlefluid::USD_FLUID > const & internalEnergy, - arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > const & dInternalEnergy, - arrayView2d< real64, constitutive::singlefluid::USD_FLUID > const & enthalpy, - arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > const & dEnthalpy, - real64 const & refIntEnergy ) - : ReactiveSingleFluidUpdate( density, dDensity, viscosity, dViscosity, numPrimarySpecies, - // equilibriumReactions, kineticReactions, - primarySpeciesConcentration, secondarySpeciesConcentration, primarySpeciesAggregateConcentration, - dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, kineticReactionRates ), - m_internalEnergy( internalEnergy ), - m_dInternalEnergy( dInternalEnergy ), - m_enthalpy( enthalpy ), - m_dEnthalpy( dEnthalpy ), - m_densRelation( densRelation ), - m_viscRelation( viscRelation ), - m_intEnergyRelation( intEnergyRelation ), - m_refIntEnergy( refIntEnergy ) - {} - - /// Default copy constructor - ThermalReactiveCompressibleSinglePhaseUpdate( ThermalReactiveCompressibleSinglePhaseUpdate const & ) = default; - - /// Default move constructor - ThermalReactiveCompressibleSinglePhaseUpdate( ThermalReactiveCompressibleSinglePhaseUpdate && ) = default; - - /// Deleted copy assignment operator - ThermalReactiveCompressibleSinglePhaseUpdate & operator=( ThermalReactiveCompressibleSinglePhaseUpdate const & ) = delete; - - /// Deleted move assignment operator - ThermalReactiveCompressibleSinglePhaseUpdate & operator=( ThermalReactiveCompressibleSinglePhaseUpdate && ) = delete; - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void compute( real64 const pressure, - real64 & density, - real64 & dDensity_dPressure, - real64 & viscosity, - real64 & dViscosity_dPressure ) const override - { - m_densRelation.compute( pressure, density, dDensity_dPressure ); - m_viscRelation.compute( pressure, viscosity, dViscosity_dPressure ); - } - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void compute( real64 const pressure, - real64 const temperature, - real64 & density, - real64 & dDensity_dPressure, - real64 & dDensity_dTemperature, - real64 & viscosity, - real64 & dViscosity_dPressure, - real64 & dViscosity_dTemperature, - real64 & internalEnergy, - real64 & dInternalEnergy_dPressure, - real64 & dInternalEnergy_dTemperature, - real64 & enthalpy, - real64 & dEnthalpy_dPressure, - real64 & dEnthalpy_dTemperature ) const override - { - m_viscRelation.compute( pressure, viscosity, dViscosity_dPressure ); - dViscosity_dTemperature = 0.0; - - m_densRelation.compute( pressure, temperature, density, dDensity_dPressure, dDensity_dTemperature ); - - /// Compute the internal energy (only sensitive to temperature) - m_intEnergyRelation.compute( temperature, internalEnergy, dInternalEnergy_dTemperature ); - dInternalEnergy_dPressure = 0.0; - - enthalpy = internalEnergy - m_refIntEnergy; - dEnthalpy_dPressure = 0.0; - dEnthalpy_dTemperature = dInternalEnergy_dTemperature; - - } - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void update( localIndex const k, - localIndex const q, - real64 const pressure ) const override - { - compute( pressure, - m_density[k][q], - m_dDensity[k][q][DerivOffset::dP], - m_viscosity[k][q], - m_dViscosity[k][q][DerivOffset::dP] ); - } - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void update( localIndex const k, - localIndex const q, - real64 const pressure, - real64 const temperature ) const override - { - compute( pressure, - temperature, - m_density[k][q], - m_dDensity[k][q][DerivOffset::dP], - m_dDensity[k][q][DerivOffset::dT], - m_viscosity[k][q], - m_dViscosity[k][q][DerivOffset::dP], - m_dViscosity[k][q][DerivOffset::dT], - m_internalEnergy[k][q], - m_dInternalEnergy[k][q][DerivOffset::dP], - m_dInternalEnergy[k][q][DerivOffset::dT], - m_enthalpy[k][q], - m_dEnthalpy[k][q][DerivOffset::dP], - m_dEnthalpy[k][q][DerivOffset::dT] ); - } - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void update( localIndex const k, - localIndex const q, - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & GEOS_UNUSED_PARAM( composition ) ) const override - { - compute( pressure, - temperature, - m_density[k][q], - m_dDensity[k][q][DerivOffset::dP], - m_dDensity[k][q][DerivOffset::dT], - m_viscosity[k][q], - m_dViscosity[k][q][DerivOffset::dP], - m_dViscosity[k][q][DerivOffset::dT], - m_internalEnergy[k][q], - m_dInternalEnergy[k][q][DerivOffset::dP], - m_dInternalEnergy[k][q][DerivOffset::dT], - m_enthalpy[k][q], - m_dEnthalpy[k][q][DerivOffset::dP], - m_dEnthalpy[k][q][DerivOffset::dT] ); - } - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void updateChemistry( localIndex const k, - localIndex const GEOS_UNUSED_PARAM( q ), - real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & primaryConc ) const override - { - for( int i=0; i < m_numPrimarySpecies; i++ ) - { - m_primarySpeciesAggregateConcentration[k][i] = primaryConc[i]; - } - - computeChemistry( pressure, - temperature, - m_primarySpeciesAggregateConcentration[k], - m_primarySpeciesConcentration[k], - m_secondarySpeciesConcentration[k], - m_kineticReactionRates[k] ); - } - - GEOS_HOST_DEVICE - GEOS_FORCE_INLINE - virtual void updateChemistryLogConc( localIndex const k, - localIndex const GEOS_UNUSED_PARAM( q ), - real64 const GEOS_UNUSED_PARAM( pressure ), - real64 const GEOS_UNUSED_PARAM( temperature ), - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimaryConc ) const override - { - for( int i=0; i < m_numPrimarySpecies; i++ ) - { - m_primarySpeciesConcentration[k][i] = std::exp( logPrimaryConc[i] ); - - m_primarySpeciesAggregateConcentration[k][i] = m_primarySpeciesConcentration[k][i]; - - m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc[k][i][i] = m_primarySpeciesConcentration[k][i]; - } - - // computeChemistry( pressure, - // temperature, - // m_primarySpeciesAggregateConcentration[k], - // m_primarySpeciesConcentration[k], - // m_secondarySpeciesConcentration[k], - // m_kineticReactionRates[k] ); - } - -private: - - /// Fluid internal energy and derivatives - arrayView2d< real64, constitutive::singlefluid::USD_FLUID > m_internalEnergy; - arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > m_dInternalEnergy; - - /// Fluid enthalpy and derivatives - arrayView2d< real64, constitutive::singlefluid::USD_FLUID > m_enthalpy; - arrayView3d< real64, constitutive::singlefluid::USD_FLUID_DER > m_dEnthalpy; - - /// Relationship between the fluid density and pressure & temperature - DensRelationType m_densRelation; - - /// Relationship between the fluid viscosity and pressure - ViscRelationType m_viscRelation; - - /// Relationship between the fluid internal energy and temperature - IntEnergyRelationType m_intEnergyRelation; - - /// Reference internal energy of the fluid - real64 const m_refIntEnergy; - -}; - -class ThermalReactiveCompressibleSinglePhase : public ReactiveCompressibleSinglePhase -{ -public: - - ThermalReactiveCompressibleSinglePhase( string const & name, Group * const parent ); - - virtual ~ThermalReactiveCompressibleSinglePhase() override; - - static string catalogName() { return "ThermalReactiveCompressibleSinglePhase"; } - - virtual string getCatalogName() const override { return catalogName(); } - - virtual void allocateConstitutiveData( dataRepository::Group & parent, - localIndex const numConstitutivePointsPerParentIndex ) override; - - using ReactiveCompressibleSinglePhase::m_densityModelType; - - /// Type of kernel wrapper for in-kernel update (TODO: support multiple EAT, not just linear) - using KernelWrapper = ThermalReactiveCompressibleSinglePhaseUpdate< ExponentApproximationType::Full, ExponentApproximationType::Linear, ExponentApproximationType::Linear >; - - /** - * @brief Create an update kernel wrapper. - * @return the wrapper - */ - KernelWrapper createKernelWrapper(); - - struct viewKeyStruct : public ReactiveCompressibleSinglePhase::viewKeyStruct - { - static constexpr char const * thermalExpansionCoeffString() { return "thermalExpansionCoeff"; } - static constexpr char const * specificHeatCapacityString() { return "specificHeatCapacity"; } - static constexpr char const * referenceTemperatureString() { return "referenceTemperature"; } - static constexpr char const * referenceInternalEnergyString() { return "referenceInternalEnergy"; } - static constexpr char const * internalEnergyModelTypeString() { return "internalEnergyModelType"; } - }; - - virtual bool isThermal() const override { return true; } - -protected: - - virtual void postInputInitialization() override; - -private: - - /// scalar fluid thermal expansion coefficient - real64 m_thermalExpansionCoeff; - - /// scalar fluid volumetric heat capacity coefficient - real64 m_specificHeatCapacity; - - /// reference temperature parameter - real64 m_referenceTemperature; - - /// reference internal energy parameter - real64 m_referenceInternalEnergy; - - /// type of internal energy model - ExponentApproximationType m_internalEnergyModelType; -}; - -} /* namespace constitutive */ - -} /* namespace geos */ - -#endif /* GEOS_CONSTITUTIVE_FLUID_SINGLEFLUID_THERMALREACTIVECOMPRESSIBLESINGLEPHASEFLUID_HPP_ */ diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt index f7f6af1aca4..9f0f4ef24b1 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt +++ b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt @@ -67,6 +67,7 @@ set( fluidFlowSolvers_headers kernels/singlePhase/reactive/FluidUpdateKernel.hpp kernels/singlePhase/reactive/FluxComputeKernel.hpp kernels/singlePhase/reactive/KernelLaunchSelectors.hpp + kernels/singlePhase/reactive/ReactionUpdateKernel.hpp kernels/singlePhase/reactive/ResidualNormKernel.hpp kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 705ae361db5..f62678c4ca8 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -23,8 +23,9 @@ #include "constitutive/ConstitutivePassThru.hpp" #include "constitutive/diffusion/DiffusionFields.hpp" #include "constitutive/diffusion/DiffusionSelector.hpp" -#include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" -#include "constitutive/fluid/multifluid/reactive/ReactiveFluidSelector.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp" +#include "constitutive/fluid/reactivefluid/ReactiveFluidSelector.hpp" #include "finiteVolume/FluxApproximationBase.hpp" #include "mesh/DomainPartition.hpp" #include "physicsSolvers/LogLevelsInfo.hpp" @@ -70,7 +71,7 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) { if( m_reactiveFluidModelName.empty() ) { - m_reactiveFluidModelName = getConstitutiveName< ReactiveSingleFluid >( subRegion ); + m_reactiveFluidModelName = getConstitutiveName< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion ); } // If at least one region has a diffusion model, consider it enabled for all @@ -86,7 +87,7 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) // Check needed to avoid errors when running in schema generation mode. if( !m_reactiveFluidModelName.empty() ) { - ReactiveSingleFluid const & reactiveFluid = cm.getConstitutiveRelation< ReactiveSingleFluid >( m_reactiveFluidModelName ); + reactivefluid::ReactiveCompressibleSinglePhaseFluid const & reactiveFluid = cm.getConstitutiveRelation< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( m_reactiveFluidModelName ); m_numPrimarySpecies = reactiveFluid.numPrimarySpecies(); m_isThermal = reactiveFluid.isThermal(); } @@ -254,8 +255,8 @@ void SinglePhaseReactiveTransport::assembleAccumulationTermsInMassBalanceAndSpec [&]( localIndex const, ElementSubRegionBase const & subRegion ) { - geos::constitutive::ReactiveSingleFluid const & fluid = - getConstitutiveModel< geos::constitutive::ReactiveSingleFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ) ); + reactivefluid::ReactiveCompressibleSinglePhaseFluid const & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ) ); geos::constitutive::CoupledSolidBase const & solid = getConstitutiveModel< geos::constitutive::CoupledSolidBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::solidNamesString() ) ); @@ -349,7 +350,7 @@ void SinglePhaseReactiveTransport::assembleFluxTerms( real64 const dt, SinglePhaseBase::FluidPropViews SinglePhaseReactiveTransport::getFluidProperties( constitutive::ConstitutiveBase const & fluid ) const { - ReactiveSingleFluid const & reactiveFluid = dynamicCast< ReactiveSingleFluid const & >( fluid ); + reactivefluid::ReactiveCompressibleSinglePhaseFluid const & reactiveFluid = dynamicCast< reactivefluid::ReactiveCompressibleSinglePhaseFluid const & >( fluid ); return { reactiveFluid.density(), reactiveFluid.dDensity(), reactiveFluid.viscosity(), @@ -391,8 +392,8 @@ void SinglePhaseReactiveTransport::updateSpeciesAmount( ElementSubRegionBase & s arrayView1d< real64 const > const volume = subRegion.getElementVolume(); arrayView1d< real64 > const deltaVolume = subRegion.getField< fields::flow::deltaVolume >(); - ReactiveSingleFluid & fluid = - getConstitutiveModel< ReactiveSingleFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); arrayView2d< real64 const, compflow::USD_COMP > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); arrayView2d< real64 const, compflow::USD_COMP > const primarySpeciesAggregateConcentration_n = fluid.primarySpeciesAggregateConcentration_n(); @@ -416,8 +417,8 @@ void SinglePhaseReactiveTransport::updateFluidModel( ObjectManagerBase & dataGro arrayView1d< real64 const > const temp = dataGroup.getField< fields::flow::temperature >(); arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc = dataGroup.getField< fields::flow::logPrimarySpeciesConcentration >(); - ReactiveSingleFluid & fluid = - getConstitutiveModel< ReactiveSingleFluid >( dataGroup, dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( dataGroup, dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ) ); constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) { @@ -431,13 +432,17 @@ void SinglePhaseReactiveTransport::initializeFluidState( MeshLevel & mesh, strin mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, [&]( localIndex const, auto & subRegion ) { - ReactiveSingleFluid const & fluid = - getConstitutiveModel< ReactiveSingleFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString())); + string const & fluidName = subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ); + + reactivefluid::ReactiveCompressibleSinglePhaseFluid const & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, fluidName); updateFluidState( subRegion ); // 2. save the initial density (for use in the single-phase poromechanics solver to compute the deltaBodyForce) fluid.initializeState(); + initializeEquilibriumReaction( subRegion ); + SinglePhaseBase::updateMass( subRegion ); updateSpeciesAmount( subRegion ); @@ -452,6 +457,25 @@ void SinglePhaseReactiveTransport::initializeFluidState( MeshLevel & mesh, strin } ); } +void SinglePhaseReactiveTransport::initializeEquilibriumReaction( ElementSubRegionBase & subRegion ) const +{ + GEOS_MARK_FUNCTION; + + arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); + arrayView1d< real64 const > const temp = subRegion.getField< fields::flow::temperature >(); + arrayView2d< real64, compflow::USD_COMP > const logPrimaryConc = subRegion.getField< fields::flow::logPrimarySpeciesConcentration >(); + + reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + + constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) + { + arrayView2d< real64 const, compflow::USD_COMP > const primaryAggregateConc = castedFluid.primarySpeciesAggregateConcentration(); + + singlePhaseReactiveBaseKernels::EquilibriumReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc, primaryAggregateConc ); + } ); +} + void SinglePhaseReactiveTransport::initializePostInitialConditionsPreSubGroups() { GEOS_MARK_FUNCTION; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index 61aa4732fff..7199841ed37 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -28,9 +28,10 @@ #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluidUpdateKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ResidualNormKernel.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp" -#include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp" namespace geos @@ -144,6 +145,8 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase virtual void initializeFluidState( MeshLevel & mesh, string_array const & regionNames ) override; + void initializeEquilibriumReaction( ElementSubRegionBase & subRegion ) const; + /** * @brief assembles the accumulation terms in total mass balance and primary species amount equation for all cells * @param dt time step diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ReactiveFluidUpdateKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ReactiveFluidUpdateKernel.hpp deleted file mode 100644 index c985d5062d2..00000000000 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ReactiveFluidUpdateKernel.hpp +++ /dev/null @@ -1,59 +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 FluidUpdateKernel.hpp - */ - -#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVEFLUIDUPDATEKERNEL_HPP -#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVEFLUIDUPDATEKERNEL_HPP - -#include "common/DataTypes.hpp" -#include "common/GEOS_RAJA_Interface.hpp" - -namespace geos -{ - -namespace reactiveTransportKernels -{ - -/******************************** FluidUpdateKernel ********************************/ - -struct FluidUpdateKernel -{ - template< typename FLUID > - static void launch( FLUID const & fluid, - arrayView1d< real64 const > const & pres, - arrayView1d< real64 const > const & temp ) - { - std::visit( [&]( auto const fluidWrapper ) - { - // For the reactive fluid, we need to - forAll< parallelDevicePolicy<> >( fluidWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) - { - for( localIndex q = 0; q < fluidWrapper.numGauss(); ++q ) - { - fluidWrapper.update( k, q, pres[k], temp[k] ); - } - } ); - }, fluid.createKernelWrapper()); - } -}; - -} // namespace reactiveTransportKernels - -} // namespace geos - -#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVEFLUIDUPDATEKERNEL_HPP diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp index 188939ac350..560a197c8c9 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp @@ -22,7 +22,7 @@ #include "common/DataLayouts.hpp" #include "common/DataTypes.hpp" -#include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp" #include "constitutive/solid/CoupledSolidBase.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/AccumulationKernels.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp" @@ -74,7 +74,7 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU AccumulationKernel( globalIndex const rankOffset, string const dofKey, SUBREGION_TYPE const & subRegion, - constitutive::ReactiveSingleFluid const & fluid, + constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid > const & fluid, constitutive::CoupledSolidBase const & solid, real64 const & dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, @@ -90,7 +90,7 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU m_primarySpeciesAggregateConcentration( fluid.primarySpeciesAggregateConcentration() ), // m_dPrimarySpeciesAggregateConcentration_dPres( fluid.dPrimarySpeciesAggregateConcentration_dPres() ), m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc( fluid.dPrimarySpeciesAggregateConcentration_dLogPrimaryConc() ), - m_primarySpeciesAggregateKineticRate( fluid.kineticReactionRates() ), + // m_primarySpeciesAggregateKineticRate( fluid.kineticReactionRates() ), // m_dPrimarySpeciesAggregateKineticRate_dPres( fluid.dPrimarySpeciesAggregateKineticRate_dPres() ), // m_dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc( fluid.dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc() ), m_primarySpeciesAggregateMole_n( subRegion.template getField< fields::flow::primarySpeciesAggregateMole_n >() ) @@ -269,8 +269,8 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // View on the derivatives of total ion concentration for the primary species wrt log of primary species concentration arrayView3d< real64 const, compflow::USD_COMP_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; - // View on the aggregate kinetic rate of primary species from all reactions - arrayView2d< real64 const, compflow::USD_COMP > m_primarySpeciesAggregateKineticRate; + // // View on the aggregate kinetic rate of primary species from all reactions + // arrayView2d< real64 const, compflow::USD_COMP > m_primarySpeciesAggregateKineticRate; // // View on the derivatives of aggregate kinetic rate of primary species wrt pressure // arrayView2d< real64 const, compflow::USD_COMP > m_dPrimarySpeciesAggregateKineticRate_dPres; @@ -309,7 +309,7 @@ class AccumulationKernelFactory globalIndex const rankOffset, string const dofKey, SUBREGION_TYPE const & subRegion, - constitutive::ReactiveSingleFluid const & fluid, + constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid > const & fluid, constitutive::CoupledSolidBase const & solid, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluidUpdateKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluidUpdateKernel.hpp index e2561c89c8e..3e9e79b6a4d 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluidUpdateKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluidUpdateKernel.hpp @@ -44,8 +44,6 @@ struct FluidUpdateKernel for( localIndex q = 0; q < fluidWrapper.numGauss(); ++q ) { fluidWrapper.update( k, q, pres[k], temp[k], logPrimaryConc[k] ); - - fluidWrapper.updateChemistryLogConc( k, q, pres[k], temp[k], logPrimaryConc[k] ); } } ); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp index 9902addd22f..0ec650bedf4 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp @@ -24,8 +24,8 @@ #include "constitutive/diffusion/DiffusionBase.hpp" #include "constitutive/solid/porosity/PorosityBase.hpp" #include "constitutive/solid/porosity/PorosityFields.hpp" -#include "constitutive/fluid/singlefluid/reactive/ReactiveSingleFluid.hpp" -#include "constitutive/fluid/multifluid/reactive/ReactiveMultiFluidFields.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/FluxComputeKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp" @@ -94,7 +94,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E fields::flow::dMobility_dLogPrimaryConc >; using ReactiveSinglePhaseFluidAccessors = - StencilMaterialAccessors< constitutive::ReactiveSingleFluid, + StencilMaterialAccessors< constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid >, fields::reactivefluid::primarySpeciesAggregateConcentration, fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimaryConc >; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp new file mode 100644 index 00000000000..069554ea192 --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp @@ -0,0 +1,79 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactionUpdateKernel.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_REACTIONUPDATEKERNEL_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_REACTIONUPDATEKERNEL_HPP + +#include "common/DataTypes.hpp" +#include "common/GEOS_RAJA_Interface.hpp" + +#include "constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp" + +namespace geos +{ + +namespace singlePhaseReactiveBaseKernels +{ + +/******************************** EquilibriumReactionUpdateKernel ********************************/ + +struct EquilibriumReactionUpdateKernel +{ + template< typename REACTIVE_FLUID > + static void launch( REACTIVE_FLUID const & fluid, + arrayView1d< real64 const > const & pres, + arrayView1d< real64 const > const & temp, + arrayView2d< real64, constitutive::reactivefluid::USD_COMP > const logPrimaryConc, + arrayView2d< real64 const, constitutive::reactivefluid::USD_COMP > const primaryAggregateConc ) + { + std::visit( [&]( auto const reactionWrapper ) + { + forAll< parallelDevicePolicy<> >( reactionWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) + { + reactionWrapper.updateEquilibriumReaction( k, pres[k], temp[k], primaryAggregateConc[k], logPrimaryConc[k] ); + } ); + }, fluid.createReactionKernelWrapper()); + } +}; + +/******************************** MixedSystemReactionUpdateKernel ********************************/ + +// struct MixedSystemReactionUpdateKernel +// { +// template< typename REACTION_WRAPPER > +// static void launch( REACTION_WRAPPER const & reactionWrapper, +// arrayView1d< real64 const > const & pres, +// arrayView1d< real64 const > const & temp, +// arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc ) +// { +// forAll< parallelDevicePolicy<> >( reactionWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) +// { +// for( localIndex q = 0; q < reactionWrapper.numGauss(); ++q ) +// { +// reactionWrapper.computeReactionRates( k, q, pres[k], temp[k], logPrimaryConc[k] ); +// } +// } ); +// } +// }; + +} // namespace singlePhaseReactiveBaseKernels + +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_REACTIVE_FLUIDUPDATEKERNEL_HPP diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp index 8911ddde9b9..cba4e23dee7 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp @@ -69,7 +69,7 @@ class AccumulationKernel : public singlePhaseReactiveBaseKernels::AccumulationKe AccumulationKernel( globalIndex const rankOffset, string const dofKey, SUBREGION_TYPE const & subRegion, - constitutive::ReactiveSingleFluid const & fluid, + constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid > const & fluid, constitutive::CoupledSolidBase const & solid, real64 const & dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, @@ -236,7 +236,7 @@ class AccumulationKernelFactory globalIndex const rankOffset, string const dofKey, SUBREGION_TYPE const & subRegion, - constitutive::ReactiveSingleFluid const & fluid, + constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid > const & fluid, constitutive::CoupledSolidBase const & solid, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp index a61571baea6..f56d9c0a710 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp @@ -92,7 +92,7 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne StencilAccessors< fields::flow::temperature >; using ThermalReactiveSinglePhaseFluidAccessors = - StencilMaterialAccessors< constitutive::ReactiveSingleFluid, + StencilMaterialAccessors< constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid >, fields::singlefluid::enthalpy, fields::singlefluid::dEnthalpy >; From 94d281fb98ea19505a1e2bdafa49ef9228640975 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Thu, 24 Apr 2025 16:21:17 -0700 Subject: [PATCH 12/12] HPCReact --- src/coreComponents/constitutive/HPCReact | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/constitutive/HPCReact b/src/coreComponents/constitutive/HPCReact index 33390bc439b..47aadc32fea 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 33390bc439bb0c9d837abdf157df37162451274b +Subproject commit 47aadc32fea4bde62b3fdfd52d1859e9f54b7371