From 538e69d3b4de5446be725ee66561629278db6db9 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Thu, 13 Mar 2025 17:52:57 -0700 Subject: [PATCH 01/66] 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/66] 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/66] 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/66] 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/66] 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/66] 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/66] 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/66] 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/66] 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/66] 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/66] 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/66] 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 From 38a649e258acc26f8bee26a1cb9a62d84ffd6dac Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Mon, 19 May 2025 16:00:35 -0700 Subject: [PATCH 13/66] interface with mixedSystem. --- src/coreComponents/constitutive/HPCReact | 2 +- .../ReactiveSinglePhaseFluid.hpp | 31 +++++++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/coreComponents/constitutive/HPCReact b/src/coreComponents/constitutive/HPCReact index 33390bc439b..cfe82872056 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 33390bc439bb0c9d837abdf157df37162451274b +Subproject commit cfe82872056a3db72e8e0eeb13a02e16b18ac382 diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index 03117773612..39c7648f9a6 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -157,17 +157,30 @@ ReactiveSinglePhaseFluid< BASE >::KernelWrapper:: template< typename BASE > 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 + computeAggregateConcentractionsAndRates( real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & logSecondarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & aggregatePrimarySpeciesConcentrations, + arraySlice2d< real64, compflow::USD_COMP - 1 > const & dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & reactionRates, + arraySlice2d< real64, compflow::USD_COMP - 1 > const & dReactionRates_dLogPrimarySpeciesConcentrations, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & aggregateSpeciesRates, + arraySlice2d< real64, compflow::USD_COMP - 1 > const & dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ) 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 ); + + MixedEquilibriumKineticReactions:: + updateMixedSystem( temperature, + m_params, + logPrimarySpeciesConcentrations, + logSecondarySpeciesConcentrations, + aggregatePrimarySpeciesConcentrations, + dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, + reactionRates, + dReactionRates_dLogPrimarySpeciesConcentrations, + aggregateSpeciesRates, + dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ) } ENUM_STRINGS( ChemicalSystemType, From 98965ab82d12b1f56c8380ac9e916abe1ccbf5eb Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Thu, 22 May 2025 10:43:18 -0700 Subject: [PATCH 14/66] enable mixed system update --- .../ReactiveSinglePhaseFluid.hpp | 245 ++++++++++++------ .../reactive/KernelLaunchSelectors.hpp | 4 +- .../reactive/ReactionUpdateKernel.hpp | 39 ++- 3 files changed, 190 insertions(+), 98 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index 7c87af5835d..9da9bc5bf5d 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -29,6 +29,7 @@ #include "constitutive/HPCReact/src/reactions/bulkGeneric/ParametersPredefined.hpp" #include "constitutive/HPCReact/src/reactions/bulkGeneric/EquilibriumReactions.hpp" +#include "constitutive/HPCReact/src/reactions/bulkGeneric/MixedEquilibriumKineticReactions.hpp" #include "constitutive/HPCReact/src/reactions/bulkGeneric/SpeciesUtilities.hpp" #include @@ -46,6 +47,7 @@ using namespace hpcReact::bulkGeneric; enum class ChemicalSystemType : integer { carbonate, + carbonateAllEquilibrium, ultramafic, simple }; @@ -61,7 +63,7 @@ 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(); } @@ -72,25 +74,30 @@ class ReactiveSinglePhaseFluid : public BASE // virtual bool isThermal() const override; - arrayView2d< real64 const, reactivefluid::USD_COMP > primarySpeciesConcentration() const - { return m_primarySpeciesConcentration; } - - arrayView2d< real64 const, reactivefluid::USD_COMP > primarySpeciesAggregateConcentration() const + arrayView3d< real64 const, reactivefluid::USD_SPECIES > primarySpeciesAggregateConcentration() const { return m_primarySpeciesAggregateConcentration; } - arrayView2d< real64 const, reactivefluid::USD_COMP > primarySpeciesAggregateConcentration_n() const + arrayView3d< real64 const, reactivefluid::USD_SPECIES > primarySpeciesAggregateConcentration_n() const { return m_primarySpeciesAggregateConcentration_n; } - arrayView3d< real64 const, reactivefluid::USD_COMP_DC > dPrimarySpeciesAggregateConcentration_dLogPrimaryConc() const - { return m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; } + arrayView4d< real64 const, reactivefluid::USD_SPECIES_DC > dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations() const + { return m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations; } - arrayView2d< real64 const, reactivefluid::USD_COMP > secondarySpeciesConcentration() const + arrayView3d< real64 const, reactivefluid::USD_SPECIES > secondarySpeciesConcentration() const { return m_secondarySpeciesConcentration; } + arrayView3d< real64 const, reactivefluid::USD_SPECIES > aggregateSpeciesRates() const + { return m_aggregateSpeciesRates; } + + arrayView4d< real64 const, reactivefluid::USD_SPECIES_DC > dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations() const + { return m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations; } + integer numPrimarySpecies() const { return m_numPrimarySpecies; } integer numSecondarySpecies() const { return m_numSecondarySpecies; } + integer numKineticReactions() const { return m_numKineticReactions; } + /** * @brief Kernel wrapper class for ReactiveSinglePhaseFluid. */ @@ -100,17 +107,25 @@ class ReactiveSinglePhaseFluid : public BASE public: - ReactionKernelWrapper( arrayView2d< real64, reactivefluid::USD_COMP > const & primarySpeciesConcentration, - arrayView2d< real64, reactivefluid::USD_COMP > const & primarySpeciesAggregateConcentration, - arrayView2d< real64, reactivefluid::USD_COMP > const & secondarySpeciesConcentration, + ReactionKernelWrapper( arrayView3d< real64, reactivefluid::USD_SPECIES > const & primarySpeciesAggregateConcentration, + arrayView4d< real64, reactivefluid::USD_SPECIES_DC > const & dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + arrayView3d< real64, reactivefluid::USD_SPECIES > const & secondarySpeciesConcentration, + arrayView3d< real64, reactivefluid::USD_SPECIES > const & kineticReactionRates, + arrayView3d< real64, reactivefluid::USD_SPECIES > const & aggregateSpeciesRates, + arrayView4d< real64, reactivefluid::USD_SPECIES_DC > const & dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, integer const numPrimarySpecies, integer const numSecondarySpecies, + integer const numKineticReactions, REACTION_PARAMS_TYPE params ): m_numPrimarySpecies( numPrimarySpecies ), m_numSecondarySpecies( numSecondarySpecies ), - m_primarySpeciesConcentration( primarySpeciesConcentration ), + m_numKineticReactions( numKineticReactions ), m_primarySpeciesAggregateConcentration( primarySpeciesAggregateConcentration ), + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations( dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations ), m_secondarySpeciesConcentration( secondarySpeciesConcentration ), + m_kineticReactionRates( kineticReactionRates ), + m_aggregateSpeciesRates( aggregateSpeciesRates ), + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations( dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ), m_params( params ) {} @@ -126,31 +141,29 @@ class ReactiveSinglePhaseFluid : public BASE 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; + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > 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; + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesTotalConcentration, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesConcentration, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > 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; + void updateMixedReactionSystem( localIndex const k, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration ) const; void computeAggregateConcentrationsAndRates( real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & logSecondarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & aggregatePrimarySpeciesConcentrations, - arraySlice2d< real64, compflow::USD_COMP - 1 > const & dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & reactionRates, - arraySlice2d< real64, compflow::USD_COMP - 1 > const & dReactionRates_dLogPrimarySpeciesConcentrations, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & aggregateSpeciesRates, - arraySlice2d< real64, compflow::USD_COMP - 1 > const & dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ) const; + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logSecondarySpeciesConcentration, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & aggregatePrimarySpeciesConcentrations, + arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & reactionRates, + arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dReactionRates_dLogPrimarySpeciesConcentrations, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & aggregateSpeciesRates, + arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ) const; protected: @@ -158,37 +171,63 @@ class ReactiveSinglePhaseFluid : public BASE integer m_numSecondarySpecies; - arrayView2d< real64, reactivefluid::USD_COMP > m_primarySpeciesConcentration; + integer m_numKineticReactions; + + arrayView3d< real64, reactivefluid::USD_SPECIES > m_primarySpeciesAggregateConcentration; + + arrayView4d< real64, reactivefluid::USD_SPECIES_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations; - arrayView2d< real64, reactivefluid::USD_COMP > m_primarySpeciesAggregateConcentration; + arrayView3d< real64, reactivefluid::USD_SPECIES > m_secondarySpeciesConcentration; - arrayView2d< real64, reactivefluid::USD_COMP > m_secondarySpeciesConcentration; + arrayView3d< real64, reactivefluid::USD_SPECIES > m_kineticReactionRates; - arrayView2d< real64, reactivefluid::USD_COMP > m_kineticReactionRates; + arrayView3d< real64, reactivefluid::USD_SPECIES > m_aggregateSpeciesRates; + + arrayView4d< real64, reactivefluid::USD_SPECIES_DC > m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations; REACTION_PARAMS_TYPE m_params; }; std::variant< typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemType >, + typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemAllEquilibriumType >, 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, + return ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemType >( m_primarySpeciesAggregateConcentration, + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, m_secondarySpeciesConcentration, + m_kineticReactionRates, + m_aggregateSpeciesRates, + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, m_numPrimarySpecies, m_numSecondarySpecies, + m_numKineticReactions, carbonateSystem ); + case ChemicalSystemType::carbonateAllEquilibrium: + return ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemAllEquilibriumType >( m_primarySpeciesAggregateConcentration, + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_secondarySpeciesConcentration, + m_kineticReactionRates, + m_aggregateSpeciesRates, + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, + m_numPrimarySpecies, + m_numSecondarySpecies, + m_numKineticReactions, + carbonateSystemAllEquilibrium ); default: - return ReactionKernelWrapper< hpcReact::bulkGeneric::simpleTestType >( m_primarySpeciesConcentration, - m_primarySpeciesAggregateConcentration, + return ReactionKernelWrapper< hpcReact::bulkGeneric::simpleTestType >( m_primarySpeciesAggregateConcentration, + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, m_secondarySpeciesConcentration, + m_kineticReactionRates, + m_aggregateSpeciesRates, + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, m_numPrimarySpecies, m_numSecondarySpecies, + m_numKineticReactions, simpleTestRateParams ); } } @@ -208,27 +247,29 @@ class ReactiveSinglePhaseFluid : public BASE integer m_numSecondarySpecies; - array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_primarySpeciesConcentration; + integer m_numKineticReactions; + + array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_secondarySpeciesConcentration; + + array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_primarySpeciesAggregateConcentration; - array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_secondarySpeciesConcentration; + array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_primarySpeciesAggregateConcentration_n; - array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_primarySpeciesAggregateConcentration; + array4d< real64, constitutive::reactivefluid::LAYOUT_SPECIES_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations; - array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_primarySpeciesAggregateConcentration_n; + array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_kineticReactionRates; - array3d< real64, constitutive::reactivefluid::LAYOUT_FLUID_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc; + array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_aggregateSpeciesRates; - array2d< real64, constitutive::reactivefluid::LAYOUT_FLUID > m_kineticReactionRates; + array4d< real64, constitutive::reactivefluid::LAYOUT_SPECIES_DC > m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations; ChemicalSystemType m_chemicalSystemType; }; // these aliases are useful in constitutive dispatch -using ReactiveSinglePhaseFluidBase = ReactiveSinglePhaseFluid< SingleFluidBase >; +using ReactiveCompressibleSinglePhaseFluid = ReactiveSinglePhaseFluid< CompressibleSinglePhaseFluid >; -using ReactiveCompressibleSinglePhaseFluid = ReactiveSinglePhaseFluid< CompressibleSinglePhaseFluid >; - -using ReactiveThermalCompressibleSinglePhaseFluid = ReactiveSinglePhaseFluid< ThermalCompressibleSinglePhaseFluid >; +using ReactiveThermalCompressibleSinglePhaseFluid = ReactiveSinglePhaseFluid< ThermalCompressibleSinglePhaseFluid >; template< typename BASE > template< typename REACTION_PARAMS_TYPE > @@ -237,10 +278,27 @@ 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 { - enforceEquilibrium( pressure, temperature, primarySpeciesAggregateConcentration, logPrimarySpeciesConcentration, m_secondarySpeciesConcentration[k] ); + integer const numPrimarySpecies = m_numPrimarySpecies; + integer const numSecondarySpecies = m_numSecondarySpecies; + + stackArray1d< real64, 10 > logPrimarySpeciesAggregateConcentration( numPrimarySpecies ); + + for( integer i=0; i < numPrimarySpecies; ++i ) + { + logPrimarySpeciesAggregateConcentration[i] = LvArray::math::log( m_primarySpeciesAggregateConcentration[k][0][i] ); + } + + stackArray1d< real64, 20 > logSecondarySpeciesConcentration( numSecondarySpecies ); + + enforceEquilibrium( pressure, temperature, logPrimarySpeciesAggregateConcentration.toSliceConst(), logPrimarySpeciesConcentration, logSecondarySpeciesConcentration.toSlice() ); + + for( integer i=0; i < numSecondarySpecies; ++i ) + { + m_secondarySpeciesConcentration[k][0][i] = LvArray::math::exp( logSecondarySpeciesConcentration[i] ); + } + } template< typename BASE > @@ -249,51 +307,86 @@ inline void ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >:: enforceEquilibrium( real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimarySpeciesAggregateConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & logSecondarySpeciesConcentrations ) const + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesAggregateConcentration, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logSecondarySpeciesConcentration ) const { GEOS_UNUSED_VAR( pressure ); // 1. We enforce equilibrium EquilibriumReactionsType::enforceEquilibrium_Aggregate( temperature, m_params, logPrimarySpeciesAggregateConcentration, logPrimarySpeciesConcentration ); + // 2. We calculate the secondary species concentration hpcReact::bulkGeneric::calculateLogSecondarySpeciesConcentration< real64, localIndex, - localIndex >( m_params, logPrimarySpeciesConcentration, logSecondarySpeciesConcentrations ); + localIndex >( m_params, logPrimarySpeciesConcentration, logSecondarySpeciesConcentration ); +} + +template< typename BASE > +template< typename REACTION_PARAMS_TYPE > +inline void +ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >:: +updateMixedReactionSystem( localIndex const k, + real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration ) const +{ + integer const numPrimarySpecies = m_numPrimarySpecies; + integer const numSecondarySpecies = m_numSecondarySpecies; + integer const numKineticReactions = m_numKineticReactions; + + stackArray1d< real64, 20 > logSecondarySpeciesConcentration( numSecondarySpecies ); + stackArray2d< real64, 20 * 20 > dReactionRates_dLogPrimarySpeciesConcentrations( numKineticReactions, numPrimarySpecies ); + + computeAggregateConcentrationsAndRates( pressure, + temperature, + logPrimarySpeciesConcentration, + logSecondarySpeciesConcentration.toSlice(), + m_primarySpeciesAggregateConcentration[k][0], + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[k][0], + m_kineticReactionRates[k][0], + dReactionRates_dLogPrimarySpeciesConcentrations.toSlice(), + m_aggregateSpeciesRates[k][0], + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations[k][0] ); + + for( integer i=0; i < numSecondarySpecies; ++i ) + { + m_secondarySpeciesConcentration[k][0][i] = LvArray::math::exp( logSecondarySpeciesConcentration[i] ); + } } template< typename BASE > template< typename REACTION_PARAMS_TYPE > inline void ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >:: - computeAggregateConcentrationsAndRates( real64 const pressure, - real64 const temperature, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & logSecondarySpeciesConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & aggregatePrimarySpeciesConcentrations, - arraySlice2d< real64, compflow::USD_COMP - 1 > const & dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & reactionRates, - arraySlice2d< real64, compflow::USD_COMP - 1 > const & dReactionRates_dLogPrimarySpeciesConcentrations, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & aggregateSpeciesRates, - arraySlice2d< real64, compflow::USD_COMP - 1 > const & dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ) const +computeAggregateConcentrationsAndRates( real64 const pressure, + real64 const temperature, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logSecondarySpeciesConcentration, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & aggregatePrimarySpeciesConcentrations, + arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & reactionRates, + arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dReactionRates_dLogPrimarySpeciesConcentrations, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & aggregateSpeciesRates, + arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ) const { GEOS_UNUSED_VAR( pressure ); - MixedEquilibriumKineticReactions:: - updateMixedSystem( temperature, - m_params, - logPrimarySpeciesConcentrations, - logSecondarySpeciesConcentrations, - aggregatePrimarySpeciesConcentrations, - dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, - reactionRates, - dReactionRates_dLogPrimarySpeciesConcentrations, - aggregateSpeciesRates, - dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ) + MixedEquilibriumKineticReactions< real64, localIndex, localIndex, true >:: + updateMixedSystem( temperature, + m_params, + logPrimarySpeciesConcentration, + logSecondarySpeciesConcentration, + aggregatePrimarySpeciesConcentrations, + dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, + reactionRates, + dReactionRates_dLogPrimarySpeciesConcentrations, + aggregateSpeciesRates, + dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ); } ENUM_STRINGS( ChemicalSystemType, "carbonate", + "carbonateAllEquilibrium", "ultramafic", "simple" ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp index a1eff26eb32..dd7bc20f0eb 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp @@ -55,9 +55,9 @@ void kernelLaunchSelectorCompSwitch( T value, LAMBDA && lambda ) case 5: { lambda( std::integral_constant< T, 5 >() ); return; } case 6: - { lambda( std::integral_constant< T, 5 >() ); return; } + { lambda( std::integral_constant< T, 6 >() ); return; } case 7: - { lambda( std::integral_constant< T, 5 >() ); return; } + { lambda( std::integral_constant< T, 7 >() ); return; } default: { GEOS_ERROR( "Unsupported number of primary species: " << value ); } } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp index 069554ea192..7cba2caf3a7 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp @@ -39,14 +39,13 @@ struct EquilibriumReactionUpdateKernel 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 ) + arrayView2d< real64, compflow::USD_COMP > const logPrimaryConc ) { 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] ); + reactionWrapper.updateEquilibriumReaction( k, pres[k], temp[k], logPrimaryConc[k] ); } ); }, fluid.createReactionKernelWrapper()); } @@ -54,23 +53,23 @@ struct EquilibriumReactionUpdateKernel /******************************** 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] ); -// } -// } ); -// } -// }; +struct MixedSystemReactionUpdateKernel +{ + template< typename REACTIVE_FLUID > + static void launch( REACTIVE_FLUID const & fluid, + arrayView1d< real64 const > const & pres, + arrayView1d< real64 const > const & temp, + arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc ) + { + std::visit( [&]( auto const reactionWrapper ) + { + forAll< parallelDevicePolicy<> >( reactionWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) + { + reactionWrapper.updateMixedReactionSystem( k, pres[k], temp[k], logPrimaryConc[k] ); + } ); + }, fluid.createReactionKernelWrapper()); + } +}; } // namespace singlePhaseReactiveBaseKernels From 776bab0dca9fff97c2f7d2d31e503405cd1175bf Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Wed, 28 May 2025 12:34:55 -0700 Subject: [PATCH 15/66] change the layout and rename some concentration arrays --- .../reactivefluid/ReactiveFluidFields.hpp | 44 ++++-- .../reactivefluid/ReactiveFluidLayouts.hpp | 146 +++++++++--------- .../ReactiveSinglePhaseFluid.cpp | 26 ++-- .../SinglePhaseReactiveTransport.cpp | 9 +- .../reactive/AccumulationKernels.hpp | 14 +- .../reactive/FluxComputeKernel.hpp | 16 +- .../reactive/ThermalAccumulationKernels.hpp | 2 +- .../reactive/ThermalFluxComputeKernel.hpp | 4 +- 8 files changed, 143 insertions(+), 118 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp index de2be4ab1ad..0b4e3226e1c 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp @@ -32,36 +32,36 @@ namespace fields namespace reactivefluid { -using array2dLayoutComp = array2d< real64, constitutive::reactivefluid::LAYOUT_COMP >; -using array3dLayoutComp_dC = array3d< real64, constitutive::reactivefluid::LAYOUT_COMP_DC >; +using array3dLayoutSpecies = array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES >; +using array4dLayoutSpecies_dC = array4d< real64, constitutive::reactivefluid::LAYOUT_SPECIES_DC >; DECLARE_FIELD( primarySpeciesConcentration, "primarySpeciesConcentration", - array2dLayoutComp, - 0, + array3dLayoutSpecies, + 1e-16, LEVEL_0, WRITE_AND_READ, "primarySpeciesConcentration" ); DECLARE_FIELD( primarySpeciesAggregateConcentration, "primarySpeciesAggregateConcentration", - array2dLayoutComp, - 0, + array3dLayoutSpecies, + 1e-16, LEVEL_0, WRITE_AND_READ, "primarySpeciesAggregateConcentration" ); DECLARE_FIELD( primarySpeciesAggregateConcentration_n, "primarySpeciesAggregateConcentration_n", - array2dLayoutComp, - 0, + array3dLayoutSpecies, + 1e-16, LEVEL_0, WRITE_AND_READ, "primarySpeciesAggregateConcentration at the previous timestep" ); -DECLARE_FIELD( dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, - "dPrimarySpeciesAggregateConcentration_dLogPrimaryConc", - array3dLayoutComp_dC, +DECLARE_FIELD( dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + "dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations", + array4dLayoutSpecies_dC, 0, LEVEL_0, WRITE_AND_READ, @@ -69,19 +69,35 @@ DECLARE_FIELD( dPrimarySpeciesAggregateConcentration_dLogPrimaryConc, DECLARE_FIELD( secondarySpeciesConcentration, "secondarySpeciesConcentration", - array2dLayoutComp, - 0, + array3dLayoutSpecies, + 1e-16, LEVEL_0, WRITE_AND_READ, "secondarySpeciesConcentration" ); DECLARE_FIELD( kineticReactionRates, "kineticReactionRates", - array2dLayoutComp, + array3dLayoutSpecies, 0, LEVEL_0, WRITE_AND_READ, "kineticReactionRates" ); + +DECLARE_FIELD( aggregateSpeciesRates, + "aggregateSpeciesRates", + array3dLayoutSpecies, + 0, + LEVEL_0, + WRITE_AND_READ, + "aggregateSpeciesRates" ); + +DECLARE_FIELD( dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, + "dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations", + array4dLayoutSpecies_dC, + 0, + LEVEL_0, + WRITE_AND_READ, + "Deivatives of aggregate concentration rates w.r.t log primary species concentration" ); } } diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp index b983063d391..d4cee0efa4b 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp @@ -33,84 +33,84 @@ 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; - }; - +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; - + +/// 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 composition array layout - using LAYOUT_COMP = RAJA::PERM_IJ; - /// Constitutive model phase composition compositional derivative array layout - using LAYOUT_COMP_DC = RAJA::PERM_IJK; - - /// 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; - +/// Constitutive model species variable array array layout +using LAYOUT_SPECIES = RAJA::PERM_IJK; +/// Constitutive model species derivative of species variable array layout +using LAYOUT_SPECIES_DC = RAJA::PERM_IJKL; + +/// Constitutive model fluid property array layout +using LAYOUT_FLUID = RAJA::PERM_IJ; +/// Constitutive model fluid property species derivative array layout +using LAYOUT_FLUID_DC = RAJA::PERM_IJK; + #endif - - /// Constitutive model phase composition unit stride dimension - static constexpr int USD_COMP = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_COMP{} ); - /// Constitutive model phase composition compositional derivative unit stride dimension - 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{} ); - /// Constitutive model fluid property compositional derivative unit stride dimension - static constexpr int USD_FLUID_DC = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_FLUID_DC{} ); + +/// Constitutive model phase composition unit stride dimension +static constexpr int USD_SPECIES = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_SPECIES{} ); +/// Constitutive model phase composition compositional derivative unit stride dimension +static constexpr int USD_SPECIES_DC = LvArray::typeManipulation::getStrideOneDimension( LAYOUT_SPECIES_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 diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index b8e30726198..5ea2d4fea28 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -43,14 +43,17 @@ ReactiveSinglePhaseFluid( string const & name, Group * const parent ): 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 = 5; - m_numSecondarySpecies = 11; + m_numPrimarySpecies = 8; // 3 for simple; 7 for carbonateSystemAllEquilibrium; 8 for carbonate + m_numSecondarySpecies = 10; // 2 for simple; 11 for carbonateSystemAllEquilibrium; 10 for carbonate + m_numKineticReactions = 1; - 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 ); + this->registerField( fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations{}, &m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations ); + this->registerField( fields::reactivefluid::kineticReactionRates{}, &m_kineticReactionRates ); + this->registerField( fields::reactivefluid::aggregateSpeciesRates{}, &m_aggregateSpeciesRates ); + this->registerField( fields::reactivefluid::dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations{}, &m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ); } template< typename BASE > @@ -86,12 +89,15 @@ void ReactiveSinglePhaseFluid< BASE >::resizeFields( localIndex const size, loca 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_primarySpeciesAggregateConcentration.resize( size, numPrimarySpecies ); - m_primarySpeciesAggregateConcentration_n.resize( size, numPrimarySpecies ); - m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc.resize( size, numPrimarySpecies, numPrimarySpecies ); + integer const numKineticReactions = this->numKineticReactions(); + + m_secondarySpeciesConcentration.resize( size, numPts, numSecondarySpecies ); + m_primarySpeciesAggregateConcentration.resize( size, numPts, numPrimarySpecies ); + m_primarySpeciesAggregateConcentration_n.resize( size, numPts, numPrimarySpecies ); + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations.resize( size, numPts, numPrimarySpecies, numPrimarySpecies ); + m_kineticReactionRates.resize( size, numPts, numKineticReactions ); + m_aggregateSpeciesRates.resize( size, numPts, numPrimarySpecies ); + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations.resize( size, numPts, numPrimarySpecies, numPrimarySpecies ); } template< typename BASE > diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index f62678c4ca8..87a6a9d5359 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -23,6 +23,7 @@ #include "constitutive/ConstitutivePassThru.hpp" #include "constitutive/diffusion/DiffusionFields.hpp" #include "constitutive/diffusion/DiffusionSelector.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp" #include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp" #include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp" #include "constitutive/fluid/reactivefluid/ReactiveFluidSelector.hpp" @@ -394,17 +395,17 @@ void SinglePhaseReactiveTransport::updateSpeciesAmount( ElementSubRegionBase & s 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(); + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration_n = fluid.primarySpeciesAggregateConcentration_n(); forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) { for( integer is = 0; is < m_numPrimarySpecies; ++is ) { - primarySpeciesAggregateMole[ei][is] = porosity[ei][0] * ( volume[ei] + deltaVolume[ei] ) * primarySpeciesAggregateConcentration[ei][is]; + primarySpeciesAggregateMole[ei][is] = porosity[ei][0] * ( volume[ei] + deltaVolume[ei] ) * primarySpeciesAggregateConcentration[ei][0][is]; if( isZero( primarySpeciesAggregateMole_n[ei][is] ) ) - primarySpeciesAggregateMole_n[ei][is] = porosity_n[ei][0] * volume[ei] * primarySpeciesAggregateConcentration_n[ei][is]; + primarySpeciesAggregateMole_n[ei][is] = porosity_n[ei][0] * volume[ei] * primarySpeciesAggregateConcentration_n[ei][0][is]; } } ); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp index 560a197c8c9..a3e06737156 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp @@ -23,6 +23,7 @@ #include "common/DataLayouts.hpp" #include "common/DataTypes.hpp" #include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp" #include "constitutive/solid/CoupledSolidBase.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/AccumulationKernels.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp" @@ -171,7 +172,8 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // stack.dPoreVolume_dLogPrimaryConc[is] * m_density[ei][0]; // } - arraySlice2d< real64 const, compflow::USD_COMP_DC - 1 > dPrimarySpeciesAggregateConcentration_dLogPrimaryConc = m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc[ei]; + arraySlice2d< real64 const, constitutive::reactivefluid::USD_SPECIES_DC - 2 > dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations = m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[ei][0]; + arraySlice2d< real64 const, constitutive::reactivefluid::USD_SPECIES_DC - 2 > dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc = m_dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc[ei][0]; for( integer is = 0; is < numSpecies; ++is ) { @@ -179,7 +181,7 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // Step 2.1: residual // 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; + stack.localResidual[is+numEqn-numSpecies] += m_primarySpeciesAggregateConcentration[ei][0][is] * stack.poreVolume; // // Reaction term // stack.localResidual[is+numEqn-numSpecies] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * @@ -187,7 +189,7 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // 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.localJacobian[is+numEqn-numSpecies][0] += stack.dPoreVolume_dPres * m_primarySpeciesAggregateConcentration[ei][0][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] ) * @@ -199,9 +201,9 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU 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 + stack.localJacobian[is+numEqn-numSpecies][js+numDof-numSpecies] = /* stack.dPoreVolume_dLogPrimaryConc[js] * + m_primarySpeciesAggregateConcentration[ei][0][is] + + */stack.poreVolume * dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[is][js]; // To // check // if // the diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp index 0ec650bedf4..84a514a0271 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp @@ -96,7 +96,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E using ReactiveSinglePhaseFluidAccessors = StencilMaterialAccessors< constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid >, fields::reactivefluid::primarySpeciesAggregateConcentration, - fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimaryConc >; + fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations >; using DiffusionAccessors = StencilMaterialAccessors< constitutive::DiffusionBase, @@ -150,7 +150,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E 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_dLogPrimarySpeciesConcentrations {} ) ), m_diffusivity( diffusionAccessors.get( fields::diffusion::diffusivity {} ) ), m_dDiffusivity_dTemp( diffusionAccessors.get( fields::diffusion::dDiffusivity_dTemperature {} ) ), m_referencePorosity( porosityAccessors.get( fields::porosity::referencePorosity {} ) ), @@ -244,7 +244,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E // 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]; + real64 const aggregateConc_i = m_primarySpeciesAggregateConc[er_up][esr_up][ei_up][0][is]; speciesFlux[is] = aggregateConc_i / fluidDens_up * fluxVal; for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) @@ -256,7 +256,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E for( integer js = 0; js < numSpecies; ++js ) { - real64 const dAggregateConc_i_dLogConc_j = m_dPrimarySpeciesAggregateConc_dLogPrimaryConc[er_up][esr_up][ei_up][is][js]; + real64 const dAggregateConc_i_dLogConc_j = m_dPrimarySpeciesAggregateConc_dLogPrimaryConc[er_up][esr_up][ei_up][0][is][js]; dSpeciesFlux_dLogConc[k_up][is][js] += dAggregateConc_i_dLogConc_j / fluidDens_up * fluxVal; } } @@ -349,13 +349,13 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E localIndex const esr = sesri[ke]; localIndex const ei = sei[ke]; - real64 const aggregateConc_i = m_primarySpeciesAggregateConc[er][esr][ei][is]; + real64 const aggregateConc_i = m_primarySpeciesAggregateConc[er][esr][ei][0][is]; speciesGrad[is] += 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]; + real64 const dAggregateConc_i_dLogConc_j = m_dPrimarySpeciesAggregateConc_dLogPrimaryConc[er][esr][ei][0][is][js]; dSpeciesGrad_i_dLogConc[ke][js] += diffusionTrans[ke] * dAggregateConc_i_dLogConc_j; } @@ -478,10 +478,10 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E ElementViewConst< arrayView2d< real64 const, compflow::USD_FLUID_DC > > const m_dMob_dLogPrimaryConc; /// Views on primary species aggregate concentration - ElementViewConst< arrayView2d< real64 const, compflow::USD_COMP > > const m_primarySpeciesAggregateConc; + ElementViewConst< arrayView3d< real64 const, constitutive::reactivefluid::USD_SPECIES > > const m_primarySpeciesAggregateConc; /// 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; + ElementViewConst< arrayView4d< real64 const, constitutive::reactivefluid::USD_SPECIES_DC > > const m_dPrimarySpeciesAggregateConc_dLogPrimaryConc; /// Views on diffusivity ElementViewConst< arrayView3d< real64 const > > const m_diffusivity; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp index cba4e23dee7..8943d8e286b 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp @@ -161,7 +161,7 @@ class AccumulationKernel : public singlePhaseReactiveBaseKernels::AccumulationKe 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.localJacobian[is+numEqn-numSpecies][numDof-numSpecies-1] += stack.dPoreVolume_dTemp * m_primarySpeciesAggregateConcentration[ei][0][is] /* + stack.poreVolume * m_dPrimarySpeciesAggregateConcentration_dTemp[ei][is] */; // // Derivative of reaction term wrt temperature diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp index f56d9c0a710..0af1651c20c 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp @@ -323,7 +323,7 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne // 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 aggregateConc_i = m_primarySpeciesAggregateConc[er_up][esr_up][ei_up][0][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; @@ -484,7 +484,7 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne // 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]; + dSpeciesGrad_dT[ke] += stack.dDiffusionTrans_dT[connectionIndex][ke] * m_primarySpeciesAggregateConc[er][esr][ei][0][is]; } for( integer ke = 0; ke < numFluxSupportPoints; ke++ ) From de8841b28a4b19b9a66b2623eeecb3d60e3d00b3 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Wed, 28 May 2025 12:35:45 -0700 Subject: [PATCH 16/66] enable mixed system update --- .../ReactiveSinglePhaseFluid.hpp | 39 +++++++++--- .../SinglePhaseReactiveTransport.cpp | 61 +++++++++++++++++-- .../SinglePhaseReactiveTransport.hpp | 13 ++++ .../reactive/AccumulationKernels.hpp | 29 ++++----- .../reactive/KernelLaunchSelectors.hpp | 4 ++ 5 files changed, 117 insertions(+), 29 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index 9da9bc5bf5d..56d23306c47 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -74,6 +74,9 @@ class ReactiveSinglePhaseFluid : public BASE // virtual bool isThermal() const override; + static constexpr integer MAX_NUM_SPECIES = 20; + static constexpr integer MAX_NUM_KINETIC_REACTIONS = 10; + arrayView3d< real64 const, reactivefluid::USD_SPECIES > primarySpeciesAggregateConcentration() const { return m_primarySpeciesAggregateConcentration; } @@ -334,24 +337,46 @@ updateMixedReactionSystem( localIndex const k, integer const numSecondarySpecies = m_numSecondarySpecies; integer const numKineticReactions = m_numKineticReactions; - stackArray1d< real64, 20 > logSecondarySpeciesConcentration( numSecondarySpecies ); - stackArray2d< real64, 20 * 20 > dReactionRates_dLogPrimarySpeciesConcentrations( numKineticReactions, numPrimarySpecies ); + stackArray1d< real64, MAX_NUM_SPECIES > primarySpeciesAggregateConcentration( numPrimarySpecies ); + stackArray1d< real64, MAX_NUM_SPECIES > logSecondarySpeciesConcentration( numSecondarySpecies ); + stackArray1d< real64, MAX_NUM_KINETIC_REACTIONS > kineticReactionRates( m_numKineticReactions ); + stackArray1d< real64, MAX_NUM_SPECIES > aggregateSpeciesRates( m_numPrimarySpecies ); + stackArray2d< real64, MAX_NUM_KINETIC_REACTIONS * MAX_NUM_SPECIES > dReactionRates_dLogPrimarySpeciesConcentrations( numKineticReactions, numPrimarySpecies ); + stackArray2d< real64, MAX_NUM_SPECIES * MAX_NUM_SPECIES > dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations( numPrimarySpecies, numPrimarySpecies ); + stackArray2d< real64, MAX_NUM_SPECIES * MAX_NUM_SPECIES > dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations( numPrimarySpecies, numPrimarySpecies ); computeAggregateConcentrationsAndRates( pressure, temperature, logPrimarySpeciesConcentration, logSecondarySpeciesConcentration.toSlice(), - m_primarySpeciesAggregateConcentration[k][0], - m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[k][0], - m_kineticReactionRates[k][0], + primarySpeciesAggregateConcentration.toSlice(), + dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations.toSlice(), + kineticReactionRates.toSlice(), dReactionRates_dLogPrimarySpeciesConcentrations.toSlice(), - m_aggregateSpeciesRates[k][0], - m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations[k][0] ); + aggregateSpeciesRates.toSlice(), + dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations.toSlice() ); + + for( int i = 0; i < numPrimarySpecies; ++i ) + { + m_primarySpeciesAggregateConcentration[k][0][i] = primarySpeciesAggregateConcentration[i]; + m_aggregateSpeciesRates[k][0][i] = aggregateSpeciesRates[i]; + + for( int j = 0; j < numPrimarySpecies; ++j ) + { + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[k][0][i][j] = dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations[i][j]; + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations[k][0][i][j] = dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations[i][j]; + } + } for( integer i=0; i < numSecondarySpecies; ++i ) { m_secondarySpeciesConcentration[k][0][i] = LvArray::math::exp( logSecondarySpeciesConcentration[i] ); } + + for( integer r=0; r < numKineticReactions; ++r ) + { + m_kineticReactionRates[k][0][r] = kineticReactionRates[r]; + } } template< typename BASE > diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 87a6a9d5359..d2b1f6e42a1 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -188,6 +188,30 @@ void SinglePhaseReactiveTransport::resetStateToBeginningOfStep( DomainPartition updateSolidInternalEnergyModel( subRegion ); updateEnergy( subRegion ); } + + updateMixedReactionSystem( subRegion ); + updateSpeciesAmount( subRegion ); + } ); + } ); +} + +void SinglePhaseReactiveTransport::implicitStepSetup( real64 const & time_n, + real64 const & dt, + DomainPartition & domain ) +{ + GEOS_MARK_FUNCTION; + + SinglePhaseBase::implicitStepSetup( time_n, dt, domain ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, [&]( localIndex const, + auto & subRegion ) + { + updateMixedReactionSystem( subRegion ); + updateSpeciesAmount( subRegion ); } ); } ); } @@ -373,6 +397,8 @@ void SinglePhaseReactiveTransport::updateState( DomainPartition & domain ) mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, [&]( localIndex const, auto & subRegion ) { + updateMixedReactionSystem( subRegion ); + updateSpeciesAmount( subRegion ); } ); } ); @@ -428,15 +454,32 @@ void SinglePhaseReactiveTransport::updateFluidModel( ObjectManagerBase & dataGro } ); } +void SinglePhaseReactiveTransport::updateMixedReactionSystem( 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 const, 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 ) + { + singlePhaseReactiveBaseKernels::MixedSystemReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc ); + } ); +} + void SinglePhaseReactiveTransport::initializeFluidState( MeshLevel & mesh, string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, [&]( localIndex const, auto & subRegion ) { string const & fluidName = subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ); - + reactivefluid::ReactiveCompressibleSinglePhaseFluid const & fluid = - getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, fluidName); + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, fluidName ); updateFluidState( subRegion ); // 2. save the initial density (for use in the single-phase poromechanics solver to compute the deltaBodyForce) @@ -444,9 +487,13 @@ void SinglePhaseReactiveTransport::initializeFluidState( MeshLevel & mesh, strin initializeEquilibriumReaction( subRegion ); + updateMixedReactionSystem( subRegion ); + SinglePhaseBase::updateMass( subRegion ); updateSpeciesAmount( subRegion ); + saveConvergedState( subRegion ); + // If the diffusion is supported, initialize the model if( m_hasDiffusion ) { @@ -471,10 +518,10 @@ void SinglePhaseReactiveTransport::initializeEquilibriumReaction( ElementSubRegi constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) { - arrayView2d< real64 const, compflow::USD_COMP > const primaryAggregateConc = castedFluid.primarySpeciesAggregateConcentration(); - - singlePhaseReactiveBaseKernels::EquilibriumReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc, primaryAggregateConc ); + singlePhaseReactiveBaseKernels::EquilibriumReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc ); } ); + + fluid.saveConvergedState(); } void SinglePhaseReactiveTransport::initializePostInitialConditionsPreSubGroups() @@ -1021,6 +1068,10 @@ void SinglePhaseReactiveTransport::saveConvergedState( ElementSubRegionBase & su { SinglePhaseBase::saveConvergedState( subRegion ); + arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc = subRegion.template getField< fields::flow::logPrimarySpeciesConcentration >(); + arrayView2d< real64, compflow::USD_COMP > const logPrimarySpeciesConc_n = subRegion.template getField< fields::flow::logPrimarySpeciesConcentration_n >(); + logPrimarySpeciesConc_n.setValues< parallelDevicePolicy<> >( logPrimaryConc ); + 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 ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index 7199841ed37..4f21a10bf26 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -94,6 +94,11 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase setupDofs( DomainPartition const & domain, DofManager & dofManager ) const override; + virtual void + implicitStepSetup( real64 const & time_n, + real64 const & dt, + DomainPartition & domain ) override final; + virtual void assembleSystem( real64 const time_n, real64 const dt, @@ -137,6 +142,8 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase virtual void updateState ( DomainPartition & domain ) override final; + void updateMixedReactionSystem( ElementSubRegionBase & subRegion ) const; + void updateSpeciesAmount( ElementSubRegionBase & subRegion ) const; virtual void updateFluidModel( ObjectManagerBase & dataGroup ) const override; @@ -147,6 +154,12 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase void initializeEquilibriumReaction( ElementSubRegionBase & subRegion ) const; + /** + * @brief Getter for the number of fluid components (species) + * @return the number of components + */ + integer numPrimarySpecies() const { return m_numPrimarySpecies; } + /** * @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/reactive/AccumulationKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp index a3e06737156..60af53d09c9 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_dPoro_dLogPrimaryConc( solid.getDporosity_dLogPrimaryConc() ), m_primarySpeciesAggregateConcentration( fluid.primarySpeciesAggregateConcentration() ), // m_dPrimarySpeciesAggregateConcentration_dPres( fluid.dPrimarySpeciesAggregateConcentration_dPres() ), - m_dPrimarySpeciesAggregateConcentration_dLogPrimaryConc( fluid.dPrimarySpeciesAggregateConcentration_dLogPrimaryConc() ), - // m_primarySpeciesAggregateKineticRate( fluid.kineticReactionRates() ), + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations( fluid.dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations() ), + m_primarySpeciesAggregateKineticRate( fluid.aggregateSpeciesRates() ), // m_dPrimarySpeciesAggregateKineticRate_dPres( fluid.dPrimarySpeciesAggregateKineticRate_dPres() ), - // m_dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc( fluid.dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc() ), + m_dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc( fluid.dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations() ), m_primarySpeciesAggregateMole_n( subRegion.template getField< fields::flow::primarySpeciesAggregateMole_n >() ) {} @@ -183,9 +183,8 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU stack.localResidual[is+numEqn-numSpecies] -= m_primarySpeciesAggregateMole_n[ei][is]; stack.localResidual[is+numEqn-numSpecies] += m_primarySpeciesAggregateConcentration[ei][0][is] * stack.poreVolume; - // // Reaction term - // stack.localResidual[is+numEqn-numSpecies] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * - // m_primarySpeciesAggregateKineticRate[is]; + // Reaction term + stack.localResidual[is+numEqn-numSpecies] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * m_primarySpeciesAggregateKineticRate[ei][0][is]; // Step 2.1: jacobian // Drivative of primary species amount in pore volume wrt pressure @@ -196,9 +195,6 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // 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] * @@ -211,8 +207,7 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // is // consistent - // stack.localJacobian[is+numEqn-numSpecies][js+numDof-numSpecies] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * - // dPrimarySpeciesTotalKineticRate_dLogPrimaryConc[is][js]; + stack.localJacobian[is+numEqn-numSpecies][js+numDof-numSpecies] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc[is][js]; } } } @@ -263,22 +258,22 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // 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; + arrayView3d< real64 const, constitutive::reactivefluid::USD_SPECIES > m_primarySpeciesAggregateConcentration; // // 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; + arrayView4d< real64 const, constitutive::reactivefluid::USD_SPECIES_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations; - // // 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 + arrayView3d< real64 const, constitutive::reactivefluid::USD_SPECIES > m_primarySpeciesAggregateKineticRate; // // 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 aggregate kinetic rate of primary species wrt log of primary species concentration - // arrayView3d< real64 const, compflow::USD_COMP_DC > m_dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc; + // View on the derivatives of aggregate kinetic rate of primary species wrt log of primary species concentration + arrayView4d< real64 const, constitutive::reactivefluid::USD_SPECIES_DC > m_dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc; // 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/KernelLaunchSelectors.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp index dd7bc20f0eb..8964b9b6ef0 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp @@ -58,6 +58,10 @@ void kernelLaunchSelectorCompSwitch( T value, LAMBDA && lambda ) { lambda( std::integral_constant< T, 6 >() ); return; } case 7: { lambda( std::integral_constant< T, 7 >() ); return; } + case 8: + { lambda( std::integral_constant< T, 8 >() ); return; } + case 9: + { lambda( std::integral_constant< T, 9 >() ); return; } default: { GEOS_ERROR( "Unsupported number of primary species: " << value ); } } From 3aab47eab5b83fad8b676623adc229687e3aaa60 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Wed, 28 May 2025 12:36:07 -0700 Subject: [PATCH 17/66] HPCReact update --- 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 cfe82872056..1bf79e1abc8 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit cfe82872056a3db72e8e0eeb13a02e16b18ac382 +Subproject commit 1bf79e1abc8b4f9374a6dd4773a3ceeb502abcf7 From 668beb241b5da3f086d9b228ee2c71d8f1551915 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Wed, 28 May 2025 12:36:24 -0700 Subject: [PATCH 18/66] added a unit test --- .../unitTests/fluidFlowTests/CMakeLists.txt | 3 +- .../testSinglePhaseReactiveTransport.cpp | 618 ++++++++++++++++++ .../testSinglePhaseReactiveTransportUtils.hpp | 227 +++++++ 3 files changed, 847 insertions(+), 1 deletion(-) create mode 100644 src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp create mode 100644 src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransportUtils.hpp diff --git a/src/coreComponents/unitTests/fluidFlowTests/CMakeLists.txt b/src/coreComponents/unitTests/fluidFlowTests/CMakeLists.txt index 48f89e0bb0b..62c816b3c18 100644 --- a/src/coreComponents/unitTests/fluidFlowTests/CMakeLists.txt +++ b/src/coreComponents/unitTests/fluidFlowTests/CMakeLists.txt @@ -5,7 +5,8 @@ set( gtest_geosx_tests testThermalSinglePhaseFlow.cpp testFlowStatistics.cpp testTransmissibility.cpp - testImmiscibleMultiphaseFlow.cpp ) + testImmiscibleMultiphaseFlow.cpp + testSinglePhaseReactiveTransport.cpp ) if( ENABLE_PVTPackage ) list( APPEND gtest_geosx_tests diff --git a/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp b/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp new file mode 100644 index 00000000000..659a69e2d5d --- /dev/null +++ b/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp @@ -0,0 +1,618 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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. + * ------------------------------------------------------------------------------------------------------------ + */ + +#include "constitutive/fluid/singlefluid/SingleFluidBase.hpp" +#include "constitutive/fluid/singlefluid/SingleFluidBase.hpp" +#include "finiteVolume/FiniteVolumeManager.hpp" +#include "finiteVolume/FluxApproximationBase.hpp" +#include "mainInterface/initialization.hpp" +#include "mainInterface/GeosxState.hpp" +#include "physicsSolvers/PhysicsSolverManager.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseBaseFields.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp" +#include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" +#include "unitTests/fluidFlowTests/testSinglePhaseReactiveTransportUtils.hpp" + +using namespace geos; +using namespace geos::dataRepository; +using namespace geos::constitutive; +using namespace geos::constitutive::reactivefluid; +using namespace geos::testing; + +CommandLineOptions g_commandLineOptions; + +// Sphinx start after input XML + +char const * xmlInputSimple = + R"xml( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )xml"; + +char const * xmlInputCarbonate = + R"xml( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )xml"; +// Sphinx end before input XML + +template< typename LAMBDA > +void testNumericalJacobian( SinglePhaseReactiveTransport & solver, + DomainPartition & domain, + real64 const perturbParameter, + real64 const relTol, + LAMBDA assembleFunction ) +{ + CRSMatrix< real64, globalIndex > const & jacobian = solver.getLocalMatrix(); + array1d< real64 > residual( jacobian.numRows() ); + + // assemble the analytical residual + solver.resetStateToBeginningOfStep( domain ); + + residual.zero(); + jacobian.zero(); + + assembleFunction( jacobian.toViewConstSizes(), residual.toView() ); + residual.move( hostMemorySpace, false ); + + // copy the analytical residual + array1d< real64 > residualOrig( residual ); + + // create the numerical jacobian + jacobian.move( hostMemorySpace ); + CRSMatrix< real64, globalIndex > jacobianFD( jacobian ); + jacobianFD.zero(); + + // fill jacobian FD + fillCellCenteredNumericalJacobian( solver, + domain, + false, + perturbParameter, + residual.toView(), + residualOrig.toView(), + jacobian.toView(), + jacobianFD.toView(), + assembleFunction ); + + // assemble the analytical jacobian + solver.resetStateToBeginningOfStep( domain ); + + residual.zero(); + jacobian.zero(); + assembleFunction( jacobian.toViewConstSizes(), residual.toView() ); + + compareLocalMatrices( jacobian.toViewConst(), jacobianFD.toViewConst(), relTol, 1e-6 ); +} + +class SinglePhaseReactiveTransportTest : public ::testing::Test +{ +public: + +SinglePhaseReactiveTransportTest(): + state( std::make_unique< CommandLineOptions >( g_commandLineOptions ) ) + {} + +protected: + + void SetUp() override + { + + setupProblemFromXML( state.getProblemManager(), xmlInputCarbonate ); + solver = &state.getProblemManager().getPhysicsSolverManager().getGroup< SinglePhaseReactiveTransport >( "SinglePhaseReactiveFlow" ); + + DomainPartition & domain = state.getProblemManager().getDomainPartition(); + + solver->setupSystem( domain, + solver->getDofManager(), + solver->getLocalMatrix(), + solver->getSystemRhs(), + solver->getSystemSolution() ); + + solver->implicitStepSetup( time, dt, domain ); + } + + static real64 constexpr time = 0.0; + static real64 constexpr dt = 1000; + static real64 constexpr eps = std::numeric_limits< real64 >::epsilon(); + + GeosxState state; + SinglePhaseReactiveTransport * solver; +}; + +real64 constexpr SinglePhaseReactiveTransportTest::time; +real64 constexpr SinglePhaseReactiveTransportTest::dt; +real64 constexpr SinglePhaseReactiveTransportTest::eps; + +TEST_F( SinglePhaseReactiveTransportTest, jacobianNumericalCheck_flux ) +{ + real64 const perturb = std::sqrt( eps ); + real64 const tol = 1e-10; // 1% error margin + + DomainPartition & domain = state.getProblemManager().getDomainPartition(); + + testNumericalJacobian( *solver, domain, perturb, tol, + [&] ( CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + // The first input parameter denotes t_n, which is unused. Just input something here. + solver->assembleFluxTerms( dt, domain, solver->getDofManager(), localMatrix, localRhs ); + } ); +} + +TEST_F( SinglePhaseReactiveTransportTest, jacobianNumericalCheck_accumulationBalance ) +{ + real64 const perturb = std::sqrt( eps ); + real64 const tol = 1e-6; // 1% error margin + + DomainPartition & domain = state.getProblemManager().getDomainPartition(); + + testNumericalJacobian( *solver, domain, perturb, tol, + [&] ( CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + solver->assembleAccumulationTermsInMassBalanceAndSpeciesAmountEqs( dt, domain, solver->getDofManager(), localMatrix, localRhs ); + } ); +} + +int main( int argc, char * * argv ) +{ + ::testing::InitGoogleTest( &argc, argv ); + g_commandLineOptions = *geos::basicSetup( argc, argv ); + int const result = RUN_ALL_TESTS(); + geos::basicCleanup(); + return result; +} diff --git a/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransportUtils.hpp b/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransportUtils.hpp new file mode 100644 index 00000000000..beda1857853 --- /dev/null +++ b/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransportUtils.hpp @@ -0,0 +1,227 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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. + * ------------------------------------------------------------------------------------------------------------ + */ + +#ifndef GEOS_TESTSINGLEPHASEREACTIVETRANSPORTUTILS_HPP +#define GEOS_TESTSINGLEPHASEREACTIVETRANSPORTUTILS_HPP + +#include "codingUtilities/UnitTestUtilities.hpp" +#include "constitutive/ConstitutiveManager.hpp" +#include "constitutive/fluid/singlefluid/SingleFluidBase.hpp" +#include "constitutive/fluid/singlefluid/SingleFluidLayouts.hpp" +#include "mesh/MeshManager.hpp" +#include "mainInterface/ProblemManager.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseBase.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseBaseFields.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseFVM.hpp" +#include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" +#include "testFlowUtils.hpp" + +namespace geos +{ + +namespace testing +{ + +void fillNumericalJacobian( arrayView1d< real64 const > const & residual, + arrayView1d< real64 const > const & residualOrig, + globalIndex const dofIndex, + real64 const eps, + CRSMatrixView< real64, globalIndex const > const & jacobian ) +{ + forAll< parallelDevicePolicy<> >( residual.size(), [=] GEOS_HOST_DEVICE ( localIndex const row ) + { + real64 const dRdX = ( residual[row] - residualOrig[row] ) / eps; + if( fabs( dRdX ) > 0.0 ) + { + jacobian.addToRow< parallelDeviceAtomic >( row, &dofIndex, &dRdX, 1 ); + } + } ); +} + +void setupProblemFromXML( ProblemManager & problemManager, char const * const xmlInput ) +{ + xmlWrapper::xmlDocument xmlDocument; + xmlWrapper::xmlResult xmlResult = xmlDocument.loadString( xmlInput ); + if( !xmlResult ) + { + GEOS_LOG_RANK_0( "XML parsed with errors!" ); + GEOS_LOG_RANK_0( "Error description: " << xmlResult.description()); + GEOS_LOG_RANK_0( "Error offset: " << xmlResult.offset ); + } + + int mpiSize = MpiWrapper::commSize( MPI_COMM_GEOS ); + + dataRepository::Group & commandLine = + problemManager.getGroup< dataRepository::Group >( problemManager.groupKeys.commandLine ); + + commandLine.registerWrapper< integer >( problemManager.viewKeys.xPartitionsOverride.key() ). + setApplyDefaultValue( mpiSize ); + + xmlWrapper::xmlNode xmlProblemNode = xmlDocument.getChild( dataRepository::keys::ProblemManager ); + problemManager.processInputFileRecursive( xmlDocument, xmlProblemNode ); + + DomainPartition & domain = problemManager.getDomainPartition(); + + constitutive::ConstitutiveManager & constitutiveManager = domain.getConstitutiveManager(); + xmlWrapper::xmlNode topLevelNode = xmlProblemNode.child( constitutiveManager.getName().c_str()); + constitutiveManager.processInputFileRecursive( xmlDocument, topLevelNode ); + + MeshManager & meshManager = problemManager.getGroup< MeshManager >( problemManager.groupKeys.meshManager ); + meshManager.generateMeshLevels( domain ); + + ElementRegionManager & elementManager = domain.getMeshBody( 0 ).getBaseDiscretization().getElemManager(); + topLevelNode = xmlProblemNode.child( elementManager.getName().c_str()); + elementManager.processInputFileRecursive( xmlDocument, topLevelNode ); + + problemManager.problemSetup(); + problemManager.applyInitialConditions(); +} + +template< typename SINGLE_REACTIVE_TRANSPORT_SOLVER, typename LAMBDA > +void fillCellCenteredNumericalJacobian( SINGLE_REACTIVE_TRANSPORT_SOLVER & solver, + DomainPartition & domain, + bool const isThermal, + real64 const perturbParameter, + arrayView1d< real64 > residual, + arrayView1d< real64 > residualOrig, + CRSMatrixView< real64, globalIndex > jacobian, + CRSMatrixView< real64, globalIndex > jacobianFD, + LAMBDA assembleFunction ) +{ + integer const numSpecies = solver.numPrimarySpecies(); + + DofManager const & dofManager = solver.getDofManager(); + string const elemDofKey = dofManager.getKey( SINGLE_REACTIVE_TRANSPORT_SOLVER::viewKeyStruct::elemDofFieldString() ); + + solver.forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, + [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + arrayView1d< integer const > const & elemGhostRank = subRegion.ghostRank(); + arrayView1d< globalIndex const > const & elemDofNumber = + subRegion.getReference< array1d< globalIndex > >( elemDofKey ); + + arrayView1d< real64 > const pres = + subRegion.getField< fields::flow::pressure >(); + arrayView2d< real64, compflow::USD_COMP > const logPrimaryConc = + subRegion.getField< fields::flow::logPrimarySpeciesConcentration >(); + + for( localIndex ei = 0; ei < subRegion.size(); ++ei ) + { + if( elemGhostRank[ei] >= 0 ) + { + continue; + } + + solver.resetStateToBeginningOfStep( domain ); + + // Step 1: compute numerical derivatives wrt pressure + + { + pres.move( hostMemorySpace, true ); // to get the correct pres after reset + real64 const dP = perturbParameter * ( pres[ei] + perturbParameter ); + pres[ei] += dP; +#if defined(GEOS_USE_CUDA) + pres.move( parallelDeviceMemorySpace, false ); +#endif + + solver.updateState( domain ); + + residual.zero(); + jacobian.zero(); + assembleFunction( jacobian.toViewConstSizes(), residual.toView() ); + + fillNumericalJacobian( residual.toViewConst(), + residualOrig.toViewConst(), + elemDofNumber[ei], + dP, + jacobianFD.toViewConstSizes() ); + } + + // Step 2: compute numerical derivatives wrt temperature + + if( isThermal ) + { + arrayView1d< real64 > const temp = + subRegion.getField< fields::flow::temperature >(); + temp.move( hostMemorySpace, false ); + + solver.resetStateToBeginningOfStep( domain ); + + temp.move( hostMemorySpace, true ); + real64 const dT = perturbParameter * ( temp[ei] + perturbParameter ); + temp[ei] += dT; +#if defined(GEOS_USE_CUDA) + temp.move( parallelDeviceMemorySpace, false ); +#endif + + // here, we make sure that rock internal energy is updated + // in other words, a call to updateFluidState would not work + solver.updateState( domain ); + + residual.zero(); + jacobian.zero(); + assembleFunction( jacobian.toViewConstSizes(), residual.toView() ); + + fillNumericalJacobian( residual.toViewConst(), + residualOrig.toViewConst(), + elemDofNumber[ei] + 1, + dT, + jacobianFD.toViewConstSizes() ); + } + + // Step 3: compute numerical derivatives wrt log primary species concentration + for( integer is = 0; is < numSpecies; ++is ) + { + solver.resetStateToBeginningOfStep( domain ); + + logPrimaryConc.move( hostMemorySpace, true ); // to get the correct logPrimaryConc after reset + real64 const dConc = perturbParameter * ( logPrimaryConc[ei][is] + perturbParameter ); + logPrimaryConc[ei][is] += dConc; +#if defined(GEOS_USE_CUDA) + logPrimaryConc.move( parallelDeviceMemorySpace, false ); +#endif + solver.updateState( domain ); + + residual.zero(); + jacobian.zero(); + assembleFunction( jacobian.toViewConstSizes(), residual.toView() ); + + integer const speciesIndexShift = (isThermal)? 2:1; + + fillNumericalJacobian( residual.toViewConst(), + residualOrig.toViewConst(), + elemDofNumber[ei] + speciesIndexShift + is, + dConc, + jacobianFD.toViewConstSizes() ); + } + + } + } ); + } ); +} + + +} // namespace testing + +} // namespace geos + +#endif //GEOS_TESTSINGLEPHASEREACTIVETRANSPORTUTILS_HPP From b40f36083a1c1914bc3ec449c1a027e84b9682fb Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Thu, 29 May 2025 10:02:09 -0700 Subject: [PATCH 19/66] cleaned up the code and enabled thermal fluid --- .../ReactiveSinglePhaseFluid.hpp | 2 - .../CompressibleSinglePhaseFluid.hpp | 2 +- .../fluid/singlefluid/SingleFluidBase.hpp | 4 +- .../ThermalCompressibleSinglePhaseFluid.hpp | 15 +- .../fluidFlow/SinglePhaseBase.cpp | 4 +- .../SinglePhaseReactiveTransport.cpp | 174 +++++++++++++----- .../SinglePhaseReactiveTransport.hpp | 2 - .../reactive/AccumulationKernels.hpp | 12 +- .../reactive/FluxComputeKernel.hpp | 7 +- .../reactive/ThermalAccumulationKernels.hpp | 16 +- .../reactive/ThermalFluxComputeKernel.hpp | 10 +- .../testSinglePhaseReactiveTransport.cpp | 164 ----------------- 12 files changed, 163 insertions(+), 249 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index 56d23306c47..f26121dc3c5 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -72,8 +72,6 @@ class ReactiveSinglePhaseFluid : public BASE virtual void allocateConstitutiveData( dataRepository::Group & parent, localIndex const numConstitutivePointsPerParentIndex ) override; - // virtual bool isThermal() const override; - static constexpr integer MAX_NUM_SPECIES = 20; static constexpr integer MAX_NUM_KINETIC_REACTIONS = 10; diff --git a/src/coreComponents/constitutive/fluid/singlefluid/CompressibleSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/singlefluid/CompressibleSinglePhaseFluid.hpp index ce243afd080..fe3d0c06ddf 100644 --- a/src/coreComponents/constitutive/fluid/singlefluid/CompressibleSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/singlefluid/CompressibleSinglePhaseFluid.hpp @@ -136,7 +136,7 @@ class CompressibleSinglePhaseUpdate : public SingleFluidBaseUpdate 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( logPrimaryConcentration ) ) const override { compute( pressure, m_density[k][q], diff --git a/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidBase.hpp b/src/coreComponents/constitutive/fluid/singlefluid/SingleFluidBase.hpp index af8c4e3fddf..7098eed2561 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] logPrimaryConc the target logPrimaryConc value + * @param[in] logPrimaryConcentration 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 & logPrimaryConc ) const = 0; + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimaryConcentration ) const = 0; }; //END_SPHINX_INCLUDE_02 diff --git a/src/coreComponents/constitutive/fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp index 59ef2713a0b..e024a048aa7 100644 --- a/src/coreComponents/constitutive/fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/singlefluid/ThermalCompressibleSinglePhaseFluid.hpp @@ -170,14 +170,23 @@ class ThermalCompressibleSinglePhaseUpdate : public SingleFluidBaseUpdate 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 + real64 const temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & GEOS_UNUSED_PARAM( logPrimaryConcentration ) ) 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::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] ); } private: diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.cpp index 3a4f750000d..e602a77bdfa 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") && (fluidModelName != "ThermalReactiveCompressibleSinglePhase")), + GEOS_THROW_IF( m_isThermal && ((fluidModelName != "ThermalCompressibleSinglePhaseFluid") && (fluidModelName != "ReactiveThermalCompressibleSinglePhaseFluid")), 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") || (fluidModelName == "ThermalReactiveCompressibleSinglePhase")), + GEOS_THROW_IF( !m_isThermal && ((fluidModelName == "ThermalCompressibleSinglePhaseFluid") || (fluidModelName == "ReactiveThermalCompressibleSinglePhaseFluid")), 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/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index d2b1f6e42a1..5a12cd5208e 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -72,7 +72,8 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) { if( m_reactiveFluidModelName.empty() ) { - m_reactiveFluidModelName = getConstitutiveName< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion ); + m_reactiveFluidModelName = m_isThermal? getConstitutiveName< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion ): + getConstitutiveName< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion ); } // If at least one region has a diffusion model, consider it enabled for all @@ -88,9 +89,16 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) // Check needed to avoid errors when running in schema generation mode. if( !m_reactiveFluidModelName.empty() ) { - reactivefluid::ReactiveCompressibleSinglePhaseFluid const & reactiveFluid = cm.getConstitutiveRelation< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( m_reactiveFluidModelName ); - m_numPrimarySpecies = reactiveFluid.numPrimarySpecies(); - m_isThermal = reactiveFluid.isThermal(); + if( m_isThermal ) + { + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid const & reactiveFluid = cm.getConstitutiveRelation< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( m_reactiveFluidModelName ); + m_numPrimarySpecies = reactiveFluid.numPrimarySpecies(); + } + else + { + reactivefluid::ReactiveCompressibleSinglePhaseFluid const & reactiveFluid = cm.getConstitutiveRelation< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( m_reactiveFluidModelName ); + m_numPrimarySpecies = reactiveFluid.numPrimarySpecies(); + } } // n_c components + one pressure ( + one temperature if needed ) @@ -280,8 +288,6 @@ void SinglePhaseReactiveTransport::assembleAccumulationTermsInMassBalanceAndSpec [&]( localIndex const, ElementSubRegionBase const & subRegion ) { - 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() ) ); @@ -289,6 +295,9 @@ void SinglePhaseReactiveTransport::assembleAccumulationTermsInMassBalanceAndSpec if( m_isThermal ) { + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid const & fluid = + getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ) ); + thermalSinglePhaseReactiveBaseKernels:: AccumulationKernelFactory:: createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, @@ -303,6 +312,9 @@ void SinglePhaseReactiveTransport::assembleAccumulationTermsInMassBalanceAndSpec } else { + reactivefluid::ReactiveCompressibleSinglePhaseFluid const & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ) ); + singlePhaseReactiveBaseKernels:: AccumulationKernelFactory:: createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, @@ -367,23 +379,10 @@ void SinglePhaseReactiveTransport::assembleFluxTerms( real64 const dt, localMatrix.toViewConstSizes(), localRhs.toView() ); } - - // To add diffusion } ); } ); } -SinglePhaseBase::FluidPropViews SinglePhaseReactiveTransport::getFluidProperties( constitutive::ConstitutiveBase const & fluid ) const -{ - reactivefluid::ReactiveCompressibleSinglePhaseFluid const & reactiveFluid = dynamicCast< reactivefluid::ReactiveCompressibleSinglePhaseFluid const & >( fluid ); - return { reactiveFluid.density(), - reactiveFluid.dDensity(), - reactiveFluid.viscosity(), - reactiveFluid.dViscosity(), - reactiveFluid.defaultDensity(), - reactiveFluid.defaultViscosity() }; -} - void SinglePhaseReactiveTransport::updateState( DomainPartition & domain ) { GEOS_MARK_FUNCTION; @@ -419,21 +418,42 @@ void SinglePhaseReactiveTransport::updateSpeciesAmount( ElementSubRegionBase & s arrayView1d< real64 const > const volume = subRegion.getElementVolume(); arrayView1d< real64 > const deltaVolume = subRegion.getField< fields::flow::deltaVolume >(); - reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = - getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); - arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); - arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration_n = fluid.primarySpeciesAggregateConcentration_n(); + if( m_isThermal ) + { + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration_n = fluid.primarySpeciesAggregateConcentration_n(); - forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + for( integer is = 0; is < m_numPrimarySpecies; ++is ) + { + primarySpeciesAggregateMole[ei][is] = porosity[ei][0] * ( volume[ei] + deltaVolume[ei] ) * primarySpeciesAggregateConcentration[ei][0][is]; + + if( isZero( primarySpeciesAggregateMole_n[ei][is] ) ) + primarySpeciesAggregateMole_n[ei][is] = porosity_n[ei][0] * volume[ei] * primarySpeciesAggregateConcentration_n[ei][0][is]; + } + } ); + } + else { - for( integer is = 0; is < m_numPrimarySpecies; ++is ) + reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration_n = fluid.primarySpeciesAggregateConcentration_n(); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) { - primarySpeciesAggregateMole[ei][is] = porosity[ei][0] * ( volume[ei] + deltaVolume[ei] ) * primarySpeciesAggregateConcentration[ei][0][is]; + for( integer is = 0; is < m_numPrimarySpecies; ++is ) + { + primarySpeciesAggregateMole[ei][is] = porosity[ei][0] * ( volume[ei] + deltaVolume[ei] ) * primarySpeciesAggregateConcentration[ei][0][is]; - if( isZero( primarySpeciesAggregateMole_n[ei][is] ) ) - primarySpeciesAggregateMole_n[ei][is] = porosity_n[ei][0] * volume[ei] * primarySpeciesAggregateConcentration_n[ei][0][is]; - } - } ); + if( isZero( primarySpeciesAggregateMole_n[ei][is] ) ) + primarySpeciesAggregateMole_n[ei][is] = porosity_n[ei][0] * volume[ei] * primarySpeciesAggregateConcentration_n[ei][0][is]; + } + } ); + } } void SinglePhaseReactiveTransport::updateFluidModel( ObjectManagerBase & dataGroup ) const @@ -444,14 +464,28 @@ 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 >(); - reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = - getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( dataGroup, dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + if( m_isThermal ) + { + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( dataGroup, dataGroup.getReference< string >( viewKeyStruct::fluidNamesString() ) ); - constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) + constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) + { + typename TYPEOFREF( castedFluid ) ::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); + singlePhaseReactiveBaseKernels::FluidUpdateKernel::launch( fluidWrapper, pres, temp, logPrimaryConc ); + } ); + } + else { - typename TYPEOFREF( castedFluid ) ::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper(); - singlePhaseReactiveBaseKernels::FluidUpdateKernel::launch( fluidWrapper, pres, temp, logPrimaryConc ); - } ); + reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( 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::updateMixedReactionSystem( ElementSubRegionBase & subRegion ) const @@ -462,13 +496,26 @@ void SinglePhaseReactiveTransport::updateMixedReactionSystem( ElementSubRegionBa arrayView1d< real64 const > const temp = subRegion.getField< fields::flow::temperature >(); arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc = subRegion.getField< fields::flow::logPrimarySpeciesConcentration >(); - reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = - getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + if( m_isThermal ) + { + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); - constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) + constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) + { + singlePhaseReactiveBaseKernels::MixedSystemReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc ); + } ); + } + else { - singlePhaseReactiveBaseKernels::MixedSystemReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc ); - } ); + reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + + constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) + { + singlePhaseReactiveBaseKernels::MixedSystemReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc ); + } ); + } } void SinglePhaseReactiveTransport::initializeFluidState( MeshLevel & mesh, string_array const & regionNames ) @@ -477,13 +524,23 @@ void SinglePhaseReactiveTransport::initializeFluidState( MeshLevel & mesh, strin auto & subRegion ) { 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(); + if( m_isThermal ) + { + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid const & fluid = + getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, fluidName ); + + fluid.initializeState(); + } + else + { + reactivefluid::ReactiveCompressibleSinglePhaseFluid const & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, fluidName ); + + fluid.initializeState(); + } initializeEquilibriumReaction( subRegion ); @@ -513,15 +570,30 @@ void SinglePhaseReactiveTransport::initializeEquilibriumReaction( ElementSubRegi 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() ) ); + if( m_isThermal ) + { + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); - constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) + constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) + { + singlePhaseReactiveBaseKernels::EquilibriumReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc ); + } ); + + fluid.saveConvergedState(); + } + else { - singlePhaseReactiveBaseKernels::EquilibriumReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc ); - } ); + reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); - fluid.saveConvergedState(); + constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) + { + singlePhaseReactiveBaseKernels::EquilibriumReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc ); + } ); + + fluid.saveConvergedState(); + } } void SinglePhaseReactiveTransport::initializePostInitialConditionsPreSubGroups() diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index 4f21a10bf26..ea947399168 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -254,8 +254,6 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase protected: - virtual FluidPropViews getFluidProperties( constitutive::ConstitutiveBase const & fluid ) const override; - /// the number of primary species in the fluid integer m_numPrimarySpecies; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp index 60af53d09c9..240cd272b2b 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp @@ -40,7 +40,7 @@ namespace singlePhaseReactiveBaseKernels * @class AccumulationKernel * @brief Define the interface for the assembly kernel in charge of accumulation */ -template< typename SUBREGION_TYPE, integer NUM_DOF, integer NUM_SPECIES > +template< typename SUBREGION_TYPE, integer NUM_DOF, integer NUM_SPECIES, typename BASE_FLUID_TYPE > class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SUBREGION_TYPE, NUM_DOF > { @@ -75,7 +75,7 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU AccumulationKernel( globalIndex const rankOffset, string const dofKey, SUBREGION_TYPE const & subRegion, - constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid > const & fluid, + constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE > const & fluid, constitutive::CoupledSolidBase const & solid, real64 const & dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, @@ -299,14 +299,14 @@ class AccumulationKernelFactory * @param[inout] localMatrix the local CRS matrix * @param[inout] localRhs the local right-hand side vector */ - template< typename POLICY, typename SUBREGION_TYPE > + template< typename POLICY, typename SUBREGION_TYPE, typename BASE_FLUID_TYPE > static void createAndLaunch( integer const numSpecies, real64 const dt, globalIndex const rankOffset, string const dofKey, SUBREGION_TYPE const & subRegion, - constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid > const & fluid, + constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE > const & fluid, constitutive::CoupledSolidBase const & solid, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) @@ -315,8 +315,8 @@ class AccumulationKernelFactory { 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 ); + AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES, BASE_FLUID_TYPE > kernel( rankOffset, dofKey, subRegion, fluid, solid, dt, localMatrix, localRhs ); + AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES, BASE_FLUID_TYPE >::template launch< POLICY >( subRegion.size(), kernel ); } ); } }; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp index 84a514a0271..bf887c55fd3 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp @@ -42,9 +42,10 @@ namespace singlePhaseReactiveFVMKernels * @tparam NUM_EQN number of equations * @tparam NUM_DOF number of degrees of freedom * @tparam STENCILWRAPPER the type of the stencil wrapper + * @tparam BASE_FLUID_TYPE the type of the base model for the reactive fluid model * @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 > +template< integer NUM_SPECIES, integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER, typename BASE_FLUID_TYPE > class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER > { public: @@ -94,7 +95,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E fields::flow::dMobility_dLogPrimaryConc >; using ReactiveSinglePhaseFluidAccessors = - StencilMaterialAccessors< constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid >, + StencilMaterialAccessors< constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE >, fields::reactivefluid::primarySpeciesAggregateConcentration, fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations >; @@ -539,7 +540,7 @@ class FluxComputeKernelFactory elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); - using KernelType = FluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, STENCILWRAPPER >; + using KernelType = FluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, STENCILWRAPPER, constitutive::CompressibleSinglePhaseFluid >; 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 index 8943d8e286b..33fa2ac0f3b 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp @@ -34,13 +34,13 @@ namespace thermalSinglePhaseReactiveBaseKernels * @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 > +template< typename SUBREGION_TYPE, integer NUM_DOF, integer NUM_SPECIES, typename BASE_FLUID_TYPE > +class AccumulationKernel : public singlePhaseReactiveBaseKernels::AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES, BASE_FLUID_TYPE > { public: - using Base = singlePhaseReactiveBaseKernels::AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES >; + using Base = singlePhaseReactiveBaseKernels::AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES, BASE_FLUID_TYPE >; using Base::numDof; using Base::numEqn; using Base::numSpecies; @@ -69,7 +69,7 @@ class AccumulationKernel : public singlePhaseReactiveBaseKernels::AccumulationKe AccumulationKernel( globalIndex const rankOffset, string const dofKey, SUBREGION_TYPE const & subRegion, - constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid > const & fluid, + constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE > const & fluid, constitutive::CoupledSolidBase const & solid, real64 const & dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, @@ -229,14 +229,14 @@ class AccumulationKernelFactory * @param[inout] localMatrix the local CRS matrix * @param[inout] localRhs the local right-hand side vector */ - template< typename POLICY, typename SUBREGION_TYPE > + template< typename POLICY, typename SUBREGION_TYPE, typename BASE_FLUID_TYPE > static void createAndLaunch( integer const numSpecies, real64 const dt, globalIndex const rankOffset, string const dofKey, SUBREGION_TYPE const & subRegion, - constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid > const & fluid, + constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE > const & fluid, constitutive::CoupledSolidBase const & solid, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) @@ -246,8 +246,8 @@ class AccumulationKernelFactory { 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 ); + AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES, BASE_FLUID_TYPE > kernel( rankOffset, dofKey, subRegion, fluid, solid, dt, localMatrix, localRhs ); + AccumulationKernel< SUBREGION_TYPE, NUM_DOF, NUM_SPECIES, BASE_FLUID_TYPE >::template launch< POLICY >( subRegion.size(), kernel ); } ); } }; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp index 0af1651c20c..ef2c9171663 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp @@ -40,8 +40,8 @@ namespace thermalSinglePhaseReactiveFVMKernels * @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 > +template< integer NUM_SPECIES, integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER, typename BASE_FLUID_TYPE > +class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, STENCILWRAPPER, BASE_FLUID_TYPE > { public: @@ -69,7 +69,7 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne using AbstractBase::m_dens; using AbstractBase::m_dDens; - using Base = singlePhaseReactiveFVMKernels::FluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, STENCILWRAPPER >; + using Base = singlePhaseReactiveFVMKernels::FluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, STENCILWRAPPER, BASE_FLUID_TYPE >; using ReactiveSinglePhaseFlowAccessors = typename Base::ReactiveSinglePhaseFlowAccessors; using ReactiveSinglePhaseFluidAccessors = typename Base::ReactiveSinglePhaseFluidAccessors; using DiffusionAccessors = typename Base::DiffusionAccessors; @@ -92,7 +92,7 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne StencilAccessors< fields::flow::temperature >; using ThermalReactiveSinglePhaseFluidAccessors = - StencilMaterialAccessors< constitutive::reactivefluid::ReactiveSinglePhaseFluid< constitutive::CompressibleSinglePhaseFluid >, + StencilMaterialAccessors< constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE >, fields::singlefluid::enthalpy, fields::singlefluid::dEnthalpy >; @@ -600,7 +600,7 @@ class FluxComputeKernelFactory elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); - using KernelType = FluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, STENCILWRAPPER >; + using KernelType = FluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, STENCILWRAPPER, constitutive::ThermalCompressibleSinglePhaseFluid >; typename KernelType::SinglePhaseFlowAccessors flowAccessors( elemManager, solverName ); typename KernelType::ReactiveSinglePhaseFlowAccessors reactiveFlowAccessors( elemManager, solverName ); typename KernelType::ThermalSinglePhaseFlowAccessors thermalFlowAccessors( elemManager, solverName ); diff --git a/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp b/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp index 659a69e2d5d..18374afa629 100644 --- a/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp @@ -36,170 +36,6 @@ CommandLineOptions g_commandLineOptions; // Sphinx start after input XML -char const * xmlInputSimple = - R"xml( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - )xml"; - char const * xmlInputCarbonate = R"xml( From 01d83b025b8711c95be6274b6a50ee275128e13a Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Thu, 29 May 2025 10:02:54 -0700 Subject: [PATCH 20/66] added thermal and isothermal mixed reaction test --- .../mixedReactionCarbonSystem.xml} | 195 +++++---- .../mixedReactionThermalCarbonSystem.xml | 378 ++++++++++++++++++ 2 files changed, 504 insertions(+), 69 deletions(-) rename inputFiles/singlePhaseFlow/{ReactiveCompressible_1d.xml => reactiveTransport/mixedReactionCarbonSystem.xml} (61%) create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionThermalCarbonSystem.xml diff --git a/inputFiles/singlePhaseFlow/ReactiveCompressible_1d.xml b/inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionCarbonSystem.xml similarity index 61% rename from inputFiles/singlePhaseFlow/ReactiveCompressible_1d.xml rename to inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionCarbonSystem.xml index a9fb09731d4..484dd0405b7 100644 --- a/inputFiles/singlePhaseFlow/ReactiveCompressible_1d.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionCarbonSystem.xml @@ -10,10 +10,9 @@ writeLinearSystem="0" logLevel="1"> @@ -24,10 +23,10 @@ @@ -41,20 +40,20 @@ + xMin="{ 1.99, -0.01, -0.01 }" + xMax="{ 3.01, 1.01, 1.01 }"/> + maxTime="1"> + target="/Outputs/vtkOutput_mixed"/> @@ -73,13 +72,14 @@ - + viscosibility="0.0" + chemicalSystemType="carbonate"/> + compressibility="1e-10"/> + permeabilityComponents="{ 2.0e-10, 2.0e-10, 2.0e-10 }"/> @@ -108,7 +108,7 @@ setNames="{ all }" objectPath="ElementRegions/Region1/block1" fieldName="rockPorosity_referencePorosity" - scale="0.05"/> + scale="0.1"/> + + + + + scale="3.76e-3"/> + scale="3.76e-1"/> - + scale="1.65e-2"/> + + + scale="-5.5833363216"/> + scale="-7.7294305998"/> - - + scale="-4.6170530778"/> + + + scale="-5.5833363216"/> + scale="-7.7294305998"/> + scale="-7.8958055517"/> + + + fieldName="logPrimarySpeciesConcentration" + component="4" + scale="-5.9949216104"/> + fieldName="logPrimarySpeciesConcentration" + component="5" + scale="0.61982840898"/> + + + + + name="vtkOutput_mixed"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionThermalCarbonSystem.xml b/inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionThermalCarbonSystem.xml new file mode 100644 index 00000000000..3160112fd45 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionThermalCarbonSystem.xml @@ -0,0 +1,378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 4a65e5e619a5e40891fb1c9ec26d72d57f995353 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Sun, 1 Jun 2025 15:01:01 -0700 Subject: [PATCH 21/66] 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 1bf79e1abc8..462beae6e50 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 1bf79e1abc8b4f9374a6dd4773a3ceeb502abcf7 +Subproject commit 462beae6e50569ed1097f662e31a7d3c1150d5ff From f816f92bcda38b7587e9daaa55a56a3fcf64b5be Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Sun, 1 Jun 2025 15:01:40 -0700 Subject: [PATCH 22/66] enabled ultramafic and avoided hard coding --- .../ReactiveSinglePhaseFluid.cpp | 36 ++++++++++++++++--- .../ReactiveSinglePhaseFluid.hpp | 13 +++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index 5ea2d4fea28..9d25e8facce 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -42,10 +42,6 @@ ReactiveSinglePhaseFluid( string const & name, Group * const parent ): 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 = 8; // 3 for simple; 7 for carbonateSystemAllEquilibrium; 8 for carbonate - m_numSecondarySpecies = 10; // 2 for simple; 11 for carbonateSystemAllEquilibrium; 10 for carbonate - m_numKineticReactions = 1; this->registerField( fields::reactivefluid::secondarySpeciesConcentration{}, &m_secondarySpeciesConcentration ); this->registerField( fields::reactivefluid::primarySpeciesAggregateConcentration{}, &m_primarySpeciesAggregateConcentration ); @@ -64,7 +60,10 @@ deliverClone( string const & name, Group * const parent ) const ReactiveSinglePhaseFluid & newConstitutiveRelation = dynamicCast< ReactiveSinglePhaseFluid & >( *clone ); - GEOS_UNUSED_VAR( newConstitutiveRelation ); + newConstitutiveRelation.m_chemicalSystemType = m_chemicalSystemType; + newConstitutiveRelation.m_numPrimarySpecies = m_numPrimarySpecies; + newConstitutiveRelation.m_numSecondarySpecies = m_numSecondarySpecies; + newConstitutiveRelation.m_numKineticReactions = m_numKineticReactions; return clone; } @@ -73,6 +72,33 @@ template< typename BASE > void ReactiveSinglePhaseFluid< BASE >::postInputInitialization() { BASE::postInputInitialization(); + + switch( m_chemicalSystemType ) + { + case ChemicalSystemType::ultramafic: + m_numPrimarySpecies = 9; + m_numSecondarySpecies = 16; + m_numKineticReactions = 5; + break; + + case ChemicalSystemType::carbonate: + m_numPrimarySpecies = 8; + m_numSecondarySpecies = 10; + m_numKineticReactions = 1; + break; + + case ChemicalSystemType::carbonateAllEquilibrium: + m_numPrimarySpecies = 7; + m_numSecondarySpecies = 11; + m_numKineticReactions = 0; + break; + + default: + m_numPrimarySpecies = 3; + m_numSecondarySpecies = 2; + m_numKineticReactions = 0; + break; + } } template< typename BASE > diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index f26121dc3c5..3d5f1ca0c9b 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -190,6 +190,7 @@ class ReactiveSinglePhaseFluid : public BASE }; std::variant< + typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::ultramaficSystemType >, typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemType >, typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemAllEquilibriumType >, typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::simpleTestType > > @@ -197,6 +198,18 @@ class ReactiveSinglePhaseFluid : public BASE { switch( m_chemicalSystemType ) { + case ChemicalSystemType::ultramafic: + return ReactionKernelWrapper< hpcReact::bulkGeneric::ultramaficSystemType >( m_primarySpeciesAggregateConcentration, + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_secondarySpeciesConcentration, + m_kineticReactionRates, + m_aggregateSpeciesRates, + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, + m_numPrimarySpecies, + m_numSecondarySpecies, + m_numKineticReactions, + ultramaficSystem ); + case ChemicalSystemType::carbonate: return ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemType >( m_primarySpeciesAggregateConcentration, m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, From 1004013b57824baee06cfe0b4f37bab1c0d6119d Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Mon, 2 Jun 2025 09:43:37 -0700 Subject: [PATCH 23/66] update hpcReact commit. --- 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 462beae6e50..8dbbaac2f90 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 462beae6e50569ed1097f662e31a7d3c1150d5ff +Subproject commit 8dbbaac2f90318615de4005fbc628a6b7dbf6bce From f5025ee1c066254454e4bc9bb9bf05f17df455ed Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Tue, 3 Jun 2025 11:48:49 -0700 Subject: [PATCH 24/66] fix compilation error. --- 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 8dbbaac2f90..8f7e7ae4acc 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 8dbbaac2f90318615de4005fbc628a6b7dbf6bce +Subproject commit 8f7e7ae4accd91427c909b7dacc855916e221ac0 From 5916829a614e57146917a679a5e323e0d3f0c162 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Wed, 4 Jun 2025 15:47:13 -0700 Subject: [PATCH 25/66] updated with HPCReact --- src/coreComponents/constitutive/HPCReact | 2 +- .../ReactiveSinglePhaseFluid.hpp | 32 +++---------------- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/src/coreComponents/constitutive/HPCReact b/src/coreComponents/constitutive/HPCReact index 462beae6e50..8f7e7ae4acc 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 462beae6e50569ed1097f662e31a7d3c1150d5ff +Subproject commit 8f7e7ae4accd91427c909b7dacc855916e221ac0 diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index 3d5f1ca0c9b..7def168b877 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -348,46 +348,24 @@ updateMixedReactionSystem( localIndex const k, integer const numSecondarySpecies = m_numSecondarySpecies; integer const numKineticReactions = m_numKineticReactions; - stackArray1d< real64, MAX_NUM_SPECIES > primarySpeciesAggregateConcentration( numPrimarySpecies ); stackArray1d< real64, MAX_NUM_SPECIES > logSecondarySpeciesConcentration( numSecondarySpecies ); - stackArray1d< real64, MAX_NUM_KINETIC_REACTIONS > kineticReactionRates( m_numKineticReactions ); - stackArray1d< real64, MAX_NUM_SPECIES > aggregateSpeciesRates( m_numPrimarySpecies ); stackArray2d< real64, MAX_NUM_KINETIC_REACTIONS * MAX_NUM_SPECIES > dReactionRates_dLogPrimarySpeciesConcentrations( numKineticReactions, numPrimarySpecies ); - stackArray2d< real64, MAX_NUM_SPECIES * MAX_NUM_SPECIES > dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations( numPrimarySpecies, numPrimarySpecies ); - stackArray2d< real64, MAX_NUM_SPECIES * MAX_NUM_SPECIES > dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations( numPrimarySpecies, numPrimarySpecies ); computeAggregateConcentrationsAndRates( pressure, temperature, logPrimarySpeciesConcentration, logSecondarySpeciesConcentration.toSlice(), - primarySpeciesAggregateConcentration.toSlice(), - dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations.toSlice(), - kineticReactionRates.toSlice(), + m_primarySpeciesAggregateConcentration[k][0], + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[k][0], + m_kineticReactionRates[k][0], dReactionRates_dLogPrimarySpeciesConcentrations.toSlice(), - aggregateSpeciesRates.toSlice(), - dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations.toSlice() ); - - for( int i = 0; i < numPrimarySpecies; ++i ) - { - m_primarySpeciesAggregateConcentration[k][0][i] = primarySpeciesAggregateConcentration[i]; - m_aggregateSpeciesRates[k][0][i] = aggregateSpeciesRates[i]; - - for( int j = 0; j < numPrimarySpecies; ++j ) - { - m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[k][0][i][j] = dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations[i][j]; - m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations[k][0][i][j] = dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations[i][j]; - } - } + m_aggregateSpeciesRates[k][0], + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations[k][0] ); for( integer i=0; i < numSecondarySpecies; ++i ) { m_secondarySpeciesConcentration[k][0][i] = LvArray::math::exp( logSecondarySpeciesConcentration[i] ); } - - for( integer r=0; r < numKineticReactions; ++r ) - { - m_kineticReactionRates[k][0][r] = kineticReactionRates[r]; - } } template< typename BASE > From 2319c5c9178a9fb452f74a7fb9af964fcfedbb89 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Wed, 4 Jun 2025 15:50:16 -0700 Subject: [PATCH 26/66] added the porosity update with kinetic reaction --- .../constitutive/CMakeLists.txt | 4 + .../constitutive/ConstitutivePassThru.hpp | 40 +++- .../ReactiveSinglePhaseFluid.cpp | 1 - .../ReactiveSinglePhaseFluid.hpp | 3 + .../constitutive/solid/ReactiveSolid.cpp | 55 +++++ .../constitutive/solid/ReactiveSolid.hpp | 147 ++++++++++++++ .../solid/porosity/ReactivePorosity.cpp | 131 ++++++++++++ .../solid/porosity/ReactivePorosity.hpp | 190 ++++++++++++++++++ .../fluidFlow/FlowSolverBase.hpp | 2 +- .../SinglePhaseReactiveTransport.cpp | 126 ++++++++++-- .../SinglePhaseReactiveTransport.hpp | 12 ++ .../SinglePhaseReactiveTransportFields.hpp | 8 + 12 files changed, 693 insertions(+), 26 deletions(-) create mode 100644 src/coreComponents/constitutive/solid/ReactiveSolid.cpp create mode 100644 src/coreComponents/constitutive/solid/ReactiveSolid.hpp create mode 100644 src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp create mode 100644 src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index b267debbcb2..8104ea5936d 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -182,6 +182,7 @@ set( constitutive_headers solid/PerfectlyPlastic.hpp solid/PorousSolid.hpp solid/PropertyConversions.hpp + solid/ReactiveSolid.hpp solid/SolidBase.hpp solid/SolidUtilities.hpp solid/SolidInternalEnergy.hpp @@ -197,6 +198,7 @@ set( constitutive_headers solid/porosity/PorosityFields.hpp solid/porosity/PressurePorosity.hpp solid/porosity/ProppantPorosity.hpp + solid/porosity/ReactivePorosity.hpp thermalConductivity/MultiPhaseConstantThermalConductivity.hpp thermalConductivity/MultiPhaseThermalConductivityBase.hpp thermalConductivity/MultiPhaseThermalConductivityFields.hpp @@ -314,6 +316,7 @@ set( constitutive_sources solid/PorousDamageSolid.cpp solid/PerfectlyPlastic.cpp solid/PorousSolid.cpp + solid/ReactiveSolid.cpp solid/SolidBase.cpp solid/SolidInternalEnergy.cpp solid/CeramicDamage.cpp @@ -321,6 +324,7 @@ set( constitutive_sources solid/porosity/PorosityBase.cpp solid/porosity/PressurePorosity.cpp solid/porosity/ProppantPorosity.cpp + solid/porosity/ReactivePorosity.cpp thermalConductivity/MultiPhaseConstantThermalConductivity.cpp thermalConductivity/MultiPhaseThermalConductivityBase.cpp thermalConductivity/MultiPhaseVolumeWeightedThermalConductivity.cpp diff --git a/src/coreComponents/constitutive/ConstitutivePassThru.hpp b/src/coreComponents/constitutive/ConstitutivePassThru.hpp index 65314e99b1e..e2077d21f8a 100644 --- a/src/coreComponents/constitutive/ConstitutivePassThru.hpp +++ b/src/coreComponents/constitutive/ConstitutivePassThru.hpp @@ -41,8 +41,10 @@ #include "solid/CompressibleSolid.hpp" #include "solid/ProppantSolid.hpp" #include "solid/CeramicDamage.hpp" +#include "solid/ReactiveSolid.hpp" #include "solid/porosity/PressurePorosity.hpp" #include "solid/porosity/ProppantPorosity.hpp" +#include "solid/porosity/ReactivePorosity.hpp" #include "permeability/ConstantPermeability.hpp" #include "permeability/CarmanKozenyPermeability.hpp" #include "permeability/ExponentialDecayPermeability.hpp" @@ -384,6 +386,34 @@ struct ConstitutivePassThru< CompressibleSolidBase > } }; +/** + * Specialization for the ReactiveSolid models. + */ +template<> +struct ConstitutivePassThru< ReactiveSolidBase > +{ + template< typename LAMBDA > + static void execute( ConstitutiveBase & constitutiveRelation, LAMBDA && lambda ) + { + ConstitutivePassThruHandler< ReactiveSolid< ReactivePorosity, ConstantPermeability >, + ReactiveSolid< ReactivePorosity, CarmanKozenyPermeability >, + ReactiveSolid< ReactivePorosity, PressurePermeability > + >::execute( constitutiveRelation, + std::forward< LAMBDA >( lambda ) ); + } + + template< typename LAMBDA > + static void execute( ConstitutiveBase const & constitutiveRelation, LAMBDA && lambda ) + { + ConstitutivePassThruHandler< ReactiveSolid< ReactivePorosity, ConstantPermeability >, + ReactiveSolid< ReactivePorosity, CarmanKozenyPermeability >, + ReactiveSolid< ReactivePorosity, PressurePermeability > + >::execute( constitutiveRelation, + std::forward< LAMBDA >( lambda ) ); + } +}; + + /** * Specialization for the ProppantModel. */ @@ -437,7 +467,10 @@ struct ConstitutivePassThru< CoupledSolidBase > PorousSolid< ElasticOrthotropic >, PorousDamageSolid< DamageSpectral< ElasticIsotropic > >, PorousDamageSolid< DamageVolDev< ElasticIsotropic > >, - PorousDamageSolid< Damage< ElasticIsotropic > > >::execute( constitutiveRelation, + PorousDamageSolid< Damage< ElasticIsotropic > >, + ReactiveSolid< ReactivePorosity, ConstantPermeability >, + ReactiveSolid< ReactivePorosity, CarmanKozenyPermeability >, + ReactiveSolid< ReactivePorosity, PressurePermeability > >::execute( constitutiveRelation, std::forward< LAMBDA >( lambda ) ); } @@ -464,7 +497,10 @@ struct ConstitutivePassThru< CoupledSolidBase > PorousSolid< ElasticOrthotropic >, PorousDamageSolid< DamageSpectral< ElasticIsotropic > >, PorousDamageSolid< DamageVolDev< ElasticIsotropic > >, - PorousDamageSolid< Damage< ElasticIsotropic > > >::execute( constitutiveRelation, + PorousDamageSolid< Damage< ElasticIsotropic > >, + ReactiveSolid< ReactivePorosity, ConstantPermeability >, + ReactiveSolid< ReactivePorosity, CarmanKozenyPermeability >, + ReactiveSolid< ReactivePorosity, PressurePermeability > >::execute( constitutiveRelation, std::forward< LAMBDA >( lambda ) ); } }; diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index 9d25e8facce..8805d997138 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -112,7 +112,6 @@ void ReactiveSinglePhaseFluid< BASE >::saveConvergedState() const 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(); integer const numKineticReactions = this->numKineticReactions(); diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index 7def168b877..228597816b1 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -90,6 +90,9 @@ class ReactiveSinglePhaseFluid : public BASE arrayView3d< real64 const, reactivefluid::USD_SPECIES > aggregateSpeciesRates() const { return m_aggregateSpeciesRates; } + arrayView3d< real64 const, reactivefluid::USD_SPECIES > kineticReactionRates() const + { return m_kineticReactionRates; } + arrayView4d< real64 const, reactivefluid::USD_SPECIES_DC > dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations() const { return m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations; } diff --git a/src/coreComponents/constitutive/solid/ReactiveSolid.cpp b/src/coreComponents/constitutive/solid/ReactiveSolid.cpp new file mode 100644 index 00000000000..eb015de05f4 --- /dev/null +++ b/src/coreComponents/constitutive/solid/ReactiveSolid.cpp @@ -0,0 +1,55 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactiveSolid.cpp + */ + +#include "ReactiveSolid.hpp" +#include "porosity/ReactivePorosity.hpp" +#include "constitutive/permeability/ConstantPermeability.hpp" +#include "constitutive/permeability/CarmanKozenyPermeability.hpp" +#include "constitutive/permeability/PressurePermeability.hpp" + +namespace geos +{ + +using namespace dataRepository; + +namespace constitutive +{ + +template< typename PORO_TYPE, + typename PERM_TYPE > +ReactiveSolid< PORO_TYPE, PERM_TYPE >::ReactiveSolid( string const & name, Group * const parent ): + CoupledSolid< NullModel, PORO_TYPE, PERM_TYPE >( name, parent ) +{} + +template< typename PORO_TYPE, + typename PERM_TYPE > +ReactiveSolid< PORO_TYPE, PERM_TYPE >::~ReactiveSolid() = default; + +// Register all ReactiveSolid model types. +typedef ReactiveSolid< ReactivePorosity, ConstantPermeability > ReactiveRockConstant; +typedef ReactiveSolid< ReactivePorosity, CarmanKozenyPermeability > ReactiveRockCK; +typedef ReactiveSolid< ReactivePorosity, PressurePermeability > ReactiveRockPressurePerm; + +REGISTER_CATALOG_ENTRY( ConstitutiveBase, ReactiveRockConstant, string const &, Group * const ) +REGISTER_CATALOG_ENTRY( ConstitutiveBase, ReactiveRockCK, string const &, Group * const ) +REGISTER_CATALOG_ENTRY( ConstitutiveBase, ReactiveRockPressurePerm, string const &, Group * const ) + +} +} /* namespace geos */ diff --git a/src/coreComponents/constitutive/solid/ReactiveSolid.hpp b/src/coreComponents/constitutive/solid/ReactiveSolid.hpp new file mode 100644 index 00000000000..5a72ba2a52d --- /dev/null +++ b/src/coreComponents/constitutive/solid/ReactiveSolid.hpp @@ -0,0 +1,147 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactiveSolid.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_SOLID_REACTIVESOLID_HPP_ +#define GEOS_CONSTITUTIVE_SOLID_REACTIVESOLID_HPP_ + +#include "constitutive/solid/CoupledSolid.hpp" +#include "constitutive/solid/porosity/ReactivePorosity.hpp" +#include "constitutive/NullModel.hpp" + +#include "constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp" + +namespace geos +{ +namespace constitutive +{ + +/** + * @brief Provides kernel-callable constitutive update routines + * + * + * @tparam PORO_TYPE type of the porosity model + * @tparam PERM_TYPE type of the permeability model + */ +template< typename PORO_TYPE, + typename PERM_TYPE > +class ReactiveSolidUpdates : public CoupledSolidUpdates< NullModel, PORO_TYPE, PERM_TYPE > +{ +public: + + /** + * @brief Constructor + */ + ReactiveSolidUpdates( NullModel const & solidModel, + PORO_TYPE const & porosityModel, + PERM_TYPE const & permModel ): + CoupledSolidUpdates< NullModel, PORO_TYPE, PERM_TYPE >( solidModel, porosityModel, permModel ) + {} + + GEOS_HOST_DEVICE + void updateStateFromPressureAndReactions( localIndex const k, + localIndex const q, + real64 const & pressure, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & kineticReactionMolarIncrements ) const + { + m_porosityUpdate.updateFromReactions( k, q, kineticReactionMolarIncrements ); + real64 const porosity = m_porosityUpdate.getPorosity( k, q ); + m_permUpdate.updateFromPressureAndPorosity( k, q, pressure, porosity ); + } + +private: + using CoupledSolidUpdates< NullModel, ReactivePorosity, PERM_TYPE >::m_solidUpdate; + using CoupledSolidUpdates< NullModel, ReactivePorosity, PERM_TYPE >::m_porosityUpdate; + using CoupledSolidUpdates< NullModel, ReactivePorosity, PERM_TYPE >::m_permUpdate; + +}; + + +/** + * @brief ReactiveSolidBase class used for dispatch of all Reactive solids. + */ +class ReactiveSolidBase +{}; + + +/** + * @brief Class to represent a porous material for flow simulations. + * It is used as an interface to access all constitutive models relative to the properties of a porous material + * for flow only simulations. + * + * @tparam PORO_TYPE type of porosity model + * @tparam PERM_TYPE type of the permeability model + */ + +template< typename PORO_TYPE, + typename PERM_TYPE > +class ReactiveSolid : public CoupledSolid< NullModel, PORO_TYPE, PERM_TYPE > +{ +public: + + + /// Alias for ElasticIsotropicUpdates + using KernelWrapper = ReactiveSolidUpdates< PORO_TYPE, PERM_TYPE >; + + /** + * @brief Constructor + * @param name Object name + * @param parent Object's parent group + */ + ReactiveSolid( string const & name, dataRepository::Group * const parent ); + + /// Destructor + virtual ~ReactiveSolid() override; + + /** + * @brief Catalog name + * @return Static catalog string + */ + static string catalogName() { return string( "ReactiveSolid" ) + PERM_TYPE::catalogName(); } + + /** + * @brief Get catalog name + * @return Catalog name string + */ + virtual string getCatalogName() const override { return catalogName(); } + + + /** + * @brief Create a instantiation of the ReactiveSolidUpdates class + * that refers to the data in this. + * @return An instantiation of ReactiveSolidUpdates. + */ + KernelWrapper createKernelUpdates() const + { + + return ReactiveSolidUpdates< PORO_TYPE, PERM_TYPE >( getSolidModel(), + getPorosityModel(), + getPermModel() ); + } +private: + using CoupledSolid< NullModel, PORO_TYPE, PERM_TYPE >::getSolidModel; + using CoupledSolid< NullModel, PORO_TYPE, PERM_TYPE >::getPorosityModel; + using CoupledSolid< NullModel, PORO_TYPE, PERM_TYPE >::getPermModel; + +}; + +} +} /* namespace geos */ + +#endif /* GEOS_CONSTITUTIVE_SOLID_REACTIVESOLID_HPP_ */ diff --git a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp new file mode 100644 index 00000000000..7060f6c2f65 --- /dev/null +++ b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp @@ -0,0 +1,131 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactivePorosity.cpp + */ + +#include "ReactivePorosity.hpp" + +namespace geos +{ + +using namespace dataRepository; + +namespace constitutive +{ + +ReactivePorosity::ReactivePorosity( string const & name, Group * const parent ): + PorosityBase( name, parent ) +{ + registerWrapper( viewKeyStruct::initialVolumeFractionsString(), &m_initialVolumeFractions ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Initial volume fractions" ); + + registerWrapper( viewKeyStruct::volumeFractionsString(), &m_volumeFractions ). + setApplyDefaultValue( 0.0 ). + setPlotLevel( PlotLevel::LEVEL_0 ). + setDescription( "Current volume fractions" ); + + registerWrapper( viewKeyStruct::volumeFractions_nString(), &m_volumeFractions_n ). + setApplyDefaultValue( 0.0 ). + setPlotLevel( PlotLevel::LEVEL_0 ). + setDescription( "Volume fractions at last time step" ); + + registerWrapper( viewKeyStruct::molarWeightsString(), &m_molarWeights ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Mineral molar weights" ); + + registerWrapper( viewKeyStruct::mineralDensitiesString(), &m_mineralDensities ). + setInputFlag( InputFlags::REQUIRED ). + setDescription( "Mineral densities" ); + + // Hard code for now + m_numKineticReactions = 1; +} + +void ReactivePorosity::allocateConstitutiveData( dataRepository::Group & parent, + localIndex const numConstitutivePointsPerParentIndex ) +{ + PorosityBase::allocateConstitutiveData( parent, numConstitutivePointsPerParentIndex ); + + resizeFields( parent.size(), numConstitutivePointsPerParentIndex ); + +} + +void ReactivePorosity::resizeFields( localIndex const size, localIndex const numPts ) +{ + integer const numKineticReactions = this->numKineticReactions(); + + m_volumeFractions.resize( size, numPts, numKineticReactions ); + m_volumeFractions_n.resize( size, numPts, numKineticReactions ); +} + +void ReactivePorosity::postInputInitialization() +{ + PorosityBase::postInputInitialization(); + + integer const numKineticReactions = this->numKineticReactions(); + + GEOS_THROW_IF_NE_MSG( m_initialVolumeFractions.size(), numKineticReactions, + GEOS_FMT( "{}: invalid number of values in attribute '{}'", getFullName(), viewKeyStruct::initialVolumeFractionsString() ), + InputError ); + + GEOS_THROW_IF_NE_MSG( m_molarWeights.size(), numKineticReactions, + GEOS_FMT( "{}: invalid number of values in attribute '{}'", getFullName(), viewKeyStruct::molarWeightsString() ), + InputError ); + + GEOS_THROW_IF_NE_MSG( m_mineralDensities.size(), numKineticReactions, + GEOS_FMT( "{}: invalid number of values in attribute '{}'", getFullName(), viewKeyStruct::mineralDensitiesString() ), + InputError ); +} + +void ReactivePorosity::saveConvergedState() const +{ + PorosityBase::saveConvergedState(); + + m_volumeFractions_n.setValues< parallelDevicePolicy<> >( m_volumeFractions.toViewConst() ); +} + +void ReactivePorosity::initializeState() const +{ + integer const numKineticReactions = this->numKineticReactions(); + + for( localIndex ei = 0; ei < m_newPorosity.size( 0 ); ++ei ) + { + for( localIndex q = 0; q < m_newPorosity.size( 1 ); ++q ) + { + m_newPorosity[ei][q] = m_referencePorosity[ei]; + } + } + + PorosityBase::initializeState(); + + for( localIndex ei = 0; ei < m_volumeFractions.size( 0 ); ++ei ) + { + for( localIndex q = 0; q < m_volumeFractions.size( 1 ); ++q ) + { + for( integer r = 0; r < numKineticReactions; ++r ) + { + m_volumeFractions[ei][q][r] = m_initialVolumeFractions[r]; + m_volumeFractions_n[ei][q][r] = m_initialVolumeFractions[r]; + } + } + } +} + +REGISTER_CATALOG_ENTRY( ConstitutiveBase, ReactivePorosity, string const &, Group * const ) +} +} /* namespace geos */ diff --git a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp new file mode 100644 index 00000000000..c36c5b59d39 --- /dev/null +++ b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp @@ -0,0 +1,190 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ReactivePorosity.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_POROSITY_REACTIVEPOROSITY_HPP_ +#define GEOS_CONSTITUTIVE_POROSITY_REACTIVEPOROSITY_HPP_ + +#include "PorosityBase.hpp" + +#include "constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp" + +namespace geos +{ +namespace constitutive +{ + +class ReactivePorosityUpdates : public PorosityBaseUpdates +{ +public: + + ReactivePorosityUpdates( arrayView2d< real64 > const & newPorosity, + arrayView2d< real64 const > const & porosity_n, + arrayView2d< real64 > const & dPorosity_dPressure, + arrayView2d< real64 > const & dPorosity_dTemperature, + arrayView2d< real64 const > const & initialPorosity, + arrayView1d< real64 const > const & referencePorosity, + arrayView3d< real64, reactivefluid::USD_SPECIES > const & volumeFractions, + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const & volumeFractions_n, + integer const numKineticReactions, + arrayView1d< real64 const > const & molarWeights, + arrayView1d< real64 const > const & mineralDensities ): + PorosityBaseUpdates( newPorosity, + porosity_n, + dPorosity_dPressure, + dPorosity_dTemperature, + initialPorosity, + referencePorosity ), + m_volumeFractions( volumeFractions ), + m_volumeFractions_n( volumeFractions_n ), + m_numKineticReactions( numKineticReactions ), + m_molarWeights( molarWeights ), + m_mineralDensities( mineralDensities ) + {} + + GEOS_HOST_DEVICE + void computePorosity( arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & kineticReactionMolarIncrements, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & volumeFractions, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & volumeFractions_n, + real64 & porosity, + real64 const & porosity_n, + integer const & numKineticReactions, + arrayView1d< real64 const > const & molarWeights, + arrayView1d< real64 const > const & mineralDensities ) const + { + real64 porosityIncrement = 0.0; + + for( integer r=0; r < numKineticReactions; ++r ) + { + real64 const volumeFractionIncrement = kineticReactionMolarIncrements[r] * molarWeights[r]/mineralDensities[r]; + volumeFractions[r] = volumeFractions_n[r] + volumeFractionIncrement; + + porosityIncrement += volumeFractionIncrement; + } + + porosity = porosity_n + porosityIncrement; // To check if it should be plus or minus + + if( porosity < 0) + { + porosity = 0; + } + else if( porosity > 1.0 ) + { + porosity = 1.0; + } + + } + + GEOS_HOST_DEVICE + void updateFromReactions( localIndex const k, + localIndex const q, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & kineticReactionMolarIncrements ) const + { + computePorosity( kineticReactionMolarIncrements, + m_volumeFractions[k][q], + m_volumeFractions_n[k][q], + m_newPorosity[k][q], + m_porosity_n[k][q], + m_numKineticReactions, + m_molarWeights, + m_mineralDensities ); + } + +protected: + + arrayView3d< real64, reactivefluid::USD_SPECIES > m_volumeFractions; + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const m_volumeFractions_n; + + integer const m_numKineticReactions; + arrayView1d< real64 const > const m_molarWeights; + arrayView1d< real64 const > const m_mineralDensities; +}; + + +class ReactivePorosity : public PorosityBase +{ +public: + ReactivePorosity( string const & name, Group * const parent ); + + virtual void allocateConstitutiveData( dataRepository::Group & parent, + localIndex const numConstitutivePointsPerParentIndex ) override; + + static string catalogName() { return "ReactivePorosity"; } + + virtual string getCatalogName() const override { return catalogName(); } + + virtual void saveConvergedState() const override; + + integer numKineticReactions() const { return m_numKineticReactions; } + + virtual void initializeState() const override; + + struct viewKeyStruct : public PorosityBase::viewKeyStruct + { + static constexpr char const * initialVolumeFractionsString() { return "initialVolumeFractions"; } + static constexpr char const * volumeFractionsString() { return "volumeFractions"; } + static constexpr char const * volumeFractions_nString() { return "volumeFractions_n"; } + static constexpr char const * molarWeightsString() { return "molarWeights"; } + static constexpr char const * mineralDensitiesString() { return "mineralDensities"; } + } viewKeys; + + using KernelWrapper = ReactivePorosityUpdates; + + /** + * @brief Create an update kernel wrapper. + * @return the wrapper + */ + KernelWrapper createKernelUpdates() const + { + return KernelWrapper( m_newPorosity, + m_porosity_n, + m_dPorosity_dPressure, + m_dPorosity_dTemperature, + m_initialPorosity, + m_referencePorosity, + m_volumeFractions, + m_volumeFractions_n, + m_numKineticReactions, + m_molarWeights, + m_mineralDensities ); + } + + +private: + virtual void postInputInitialization() override; + + virtual void resizeFields( localIndex const size, localIndex const numPts ); + + array1d< real64 > m_initialVolumeFractions; + + array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_volumeFractions; + array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_volumeFractions_n; + + integer m_numKineticReactions; + array1d< real64 > m_molarWeights; + array1d< real64 > m_mineralDensities; + +}; + + +}/* namespace constitutive */ + +} /* namespace geos */ + + +#endif //GEOS_CONSTITUTIVE_POROSITY_REACTIVEPOROSITY_HPP_ diff --git a/src/coreComponents/physicsSolvers/fluidFlow/FlowSolverBase.hpp b/src/coreComponents/physicsSolvers/fluidFlow/FlowSolverBase.hpp index 172cd902b2a..a86326ed04d 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/FlowSolverBase.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/FlowSolverBase.hpp @@ -105,7 +105,7 @@ class FlowSolverBase : public PhysicsSolverBase void enableJumpStabilization() { m_isJumpStabilized = true; } - void updatePorosityAndPermeability( CellElementSubRegion & subRegion ) const; + virtual void updatePorosityAndPermeability( CellElementSubRegion & subRegion ) const; virtual void updatePorosityAndPermeability( SurfaceElementSubRegion & subRegion ) const; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 5a12cd5208e..b2b6fa71ee0 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -44,11 +44,16 @@ SinglePhaseReactiveTransport::SinglePhaseReactiveTransport( const string & name, Group * const parent ): SinglePhaseBase( name, parent ), m_numPrimarySpecies( 0 ), - m_hasDiffusion( 0 ) + m_numKineticReactions( 0 ), + m_hasDiffusion( 0 ), + m_isUpdateReactivePorosity( 0 ) { // To add modeling parameters we want to add here - addLogLevel< logInfo::Convergence >(); + this->registerWrapper( viewKeyStruct::isUpdateReactivePorosityString(), &m_isUpdateReactivePorosity ). + setApplyDefaultValue( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Flag indicating whether use the reactive porosity or not" ); } // TODO: we need to update the class of ReactiveSingleFluid to be consistent with the chemistry module!!! @@ -93,11 +98,13 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) { reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid const & reactiveFluid = cm.getConstitutiveRelation< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( m_reactiveFluidModelName ); m_numPrimarySpecies = reactiveFluid.numPrimarySpecies(); + m_numKineticReactions = reactiveFluid.numKineticReactions(); } else { reactivefluid::ReactiveCompressibleSinglePhaseFluid const & reactiveFluid = cm.getConstitutiveRelation< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( m_reactiveFluidModelName ); m_numPrimarySpecies = reactiveFluid.numPrimarySpecies(); + m_numKineticReactions = reactiveFluid.numKineticReactions(); } } @@ -144,6 +151,9 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) subRegion.registerField< bcLogPrimarySpeciesConcentration >( getName() ). reference().resizeDimension< 1 >( m_numPrimarySpecies ); + + subRegion.registerField< kineticReactionMolarIncrements >( getName() ). + reference().resizeDimension< 1 >( m_numKineticReactions ); } ); } ); } @@ -173,30 +183,21 @@ void SinglePhaseReactiveTransport::resetStateToBeginningOfStep( DomainPartition 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 ); + } ); + } ); + + SinglePhaseBase::resetStateToBeginningOfStep( domain ); - 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 ); - } - + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, [&]( localIndex const, + auto & subRegion ) + { updateMixedReactionSystem( subRegion ); updateSpeciesAmount( subRegion ); } ); @@ -232,6 +233,18 @@ void SinglePhaseReactiveTransport::implicitStepComplete( real64 const & time, SinglePhaseBase::implicitStepComplete( time, dt, domain ); + // Update molar increments of kinetic reactions for porosity update + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + updateKineticReactionMolarIncrements( dt, subRegion ); + } ); + } ); + if( m_hasDiffusion ) { forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, @@ -456,6 +469,43 @@ void SinglePhaseReactiveTransport::updateSpeciesAmount( ElementSubRegionBase & s } } +void SinglePhaseReactiveTransport::updateKineticReactionMolarIncrements( real64 const dt, + ElementSubRegionBase & subRegion ) const +{ + GEOS_MARK_FUNCTION; + + arrayView2d< real64, compflow::USD_COMP > const kineticReactionMolarIncrements = subRegion.getField< fields::flow::kineticReactionMolarIncrements >(); + + if( m_isThermal ) + { + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const kineticReactionRates = fluid.kineticReactionRates(); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + for( integer r = 0; r < m_numKineticReactions; ++r ) + { + kineticReactionMolarIncrements[ei][r] = dt* kineticReactionRates[ei][0][r]; + } + } ); + } + else + { + reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const kineticReactionRates = fluid.kineticReactionRates(); + + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + for( integer r = 0; r < m_numKineticReactions; ++r ) + { + kineticReactionMolarIncrements[ei][r] = dt* kineticReactionRates[ei][0][r]; + } + } ); + } +} + void SinglePhaseReactiveTransport::updateFluidModel( ObjectManagerBase & dataGroup ) const { GEOS_MARK_FUNCTION; @@ -488,6 +538,38 @@ void SinglePhaseReactiveTransport::updateFluidModel( ObjectManagerBase & dataGro } } +void SinglePhaseReactiveTransport::updatePorosityAndPermeability( CellElementSubRegion & subRegion ) const +{ + GEOS_MARK_FUNCTION; + + if( m_isUpdateReactivePorosity ) + { + arrayView1d< real64 const > const & pressure = subRegion.getField< fields::flow::pressure >(); + arrayView2d< real64 const, compflow::USD_COMP > const kineticReactionMolarIncrements = subRegion.getField< fields::flow::kineticReactionMolarIncrements >(); + + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + CoupledSolidBase & porousSolid = subRegion.template getConstitutiveModel< CoupledSolidBase >( solidName ); + + constitutive::ConstitutivePassThru< ReactiveSolidBase >::execute( porousSolid, [=, &subRegion] ( auto & castedPorousSolid ) + { + typename TYPEOFREF( castedPorousSolid ) ::KernelWrapper porousWrapper = castedPorousSolid.createKernelUpdates(); + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_DEVICE ( localIndex const k ) + { + for( localIndex q = 0; q < porousWrapper.numGauss(); ++q ) + { + porousWrapper.updateStateFromPressureAndReactions( k, q, + pressure[k], + kineticReactionMolarIncrements[k] ); + } + } ); + } ); + } + else + { + FlowSolverBase::updatePorosityAndPermeability( subRegion ); + } +} + void SinglePhaseReactiveTransport::updateMixedReactionSystem( ElementSubRegionBase & subRegion ) const { GEOS_MARK_FUNCTION; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index ea947399168..58d32505f60 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -146,8 +146,13 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase void updateSpeciesAmount( ElementSubRegionBase & subRegion ) const; + void updateKineticReactionMolarIncrements( real64 const dt, + ElementSubRegionBase & subRegion ) const; + virtual void updateFluidModel( ObjectManagerBase & dataGroup ) const override; + virtual void updatePorosityAndPermeability( CellElementSubRegion & subRegion ) const override; + virtual void initializePostInitialConditionsPreSubGroups() override; virtual void initializeFluidState( MeshLevel & mesh, string_array const & regionNames ) override; @@ -250,6 +255,7 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase struct viewKeyStruct : SinglePhaseBase::viewKeyStruct { static constexpr char const * diffusionNamesString() { return "diffusionNames"; } + static constexpr char const * isUpdateReactivePorosityString() { return "isUpdateReactivePorosity"; } }; protected: @@ -257,11 +263,17 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase /// the number of primary species in the fluid integer m_numPrimarySpecies; + /// the number of kinetic reactions + integer m_numKineticReactions; + /// name of the reactive fluid constitutive model string m_reactiveFluidModelName; /// flag to determine whether or not to apply diffusion integer m_hasDiffusion; + + /// flag to determine whether or not to use the reactive porosity + integer m_isUpdateReactivePorosity; }; template< typename OBJECT_TYPE > diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp index 3aa6c8f8cd4..432696405af 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp @@ -75,6 +75,14 @@ DECLARE_FIELD( primarySpeciesAggregateMole_n, WRITE_AND_READ, "Aggregate amount of primary species in mole at the previous converged time step" ); +DECLARE_FIELD( kineticReactionMolarIncrements, + "kineticReactionMolarIncrements", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "Molar increment in the current timestep for kinetic reactions" ); + DECLARE_FIELD( dMobility_dLogPrimaryConc, "dMobility_dLogPrimaryConc", array2dLayoutFluid_dC, From c6a1a42bf194cb7503f432d74daccabdbe695c0a Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Fri, 6 Jun 2025 20:50:02 -0700 Subject: [PATCH 27/66] added some checks if using the reactive porosity model --- .../solid/porosity/ReactivePorosity.cpp | 48 +++++++++++-------- .../solid/porosity/ReactivePorosity.hpp | 4 ++ .../SinglePhaseReactiveTransport.cpp | 36 ++++++++++++++ .../SinglePhaseReactiveTransport.hpp | 6 +++ 4 files changed, 73 insertions(+), 21 deletions(-) diff --git a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp index 7060f6c2f65..c9e46cccd27 100644 --- a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp +++ b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp @@ -51,9 +51,34 @@ ReactivePorosity::ReactivePorosity( string const & name, Group * const parent ): registerWrapper( viewKeyStruct::mineralDensitiesString(), &m_mineralDensities ). setInputFlag( InputFlags::REQUIRED ). setDescription( "Mineral densities" ); +} + +std::unique_ptr< ConstitutiveBase > ReactivePorosity::deliverClone( string const & name, Group * const parent ) const +{ + std::unique_ptr< ConstitutiveBase > clone = ConstitutiveBase::deliverClone( name, parent ); + + ReactivePorosity & newConstitutiveRelation = dynamicCast< ReactivePorosity & >( *clone ); - // Hard code for now - m_numKineticReactions = 1; + newConstitutiveRelation.m_numKineticReactions = m_numKineticReactions; + + return clone; +} + +void ReactivePorosity::postInputInitialization() +{ + PorosityBase::postInputInitialization(); + + GEOS_THROW_IF_NE_MSG( m_molarWeights.size(), m_initialVolumeFractions.size(), + GEOS_FMT( "{}: mismatch in number of components in porosity model attribute '{}' and '{}", + getFullName(), viewKeyStruct::molarWeightsString(), viewKeyStruct::initialVolumeFractionsString() ), + InputError ); + + GEOS_THROW_IF_NE_MSG( m_mineralDensities.size(), m_initialVolumeFractions.size(), + GEOS_FMT( "{}: mismatch in number of components in porosity model attribute '{}' and '{}", + getFullName(), viewKeyStruct::mineralDensitiesString(), viewKeyStruct::initialVolumeFractionsString() ), + InputError ); + + m_numKineticReactions = m_initialVolumeFractions.size(); } void ReactivePorosity::allocateConstitutiveData( dataRepository::Group & parent, @@ -73,25 +98,6 @@ void ReactivePorosity::resizeFields( localIndex const size, localIndex const num m_volumeFractions_n.resize( size, numPts, numKineticReactions ); } -void ReactivePorosity::postInputInitialization() -{ - PorosityBase::postInputInitialization(); - - integer const numKineticReactions = this->numKineticReactions(); - - GEOS_THROW_IF_NE_MSG( m_initialVolumeFractions.size(), numKineticReactions, - GEOS_FMT( "{}: invalid number of values in attribute '{}'", getFullName(), viewKeyStruct::initialVolumeFractionsString() ), - InputError ); - - GEOS_THROW_IF_NE_MSG( m_molarWeights.size(), numKineticReactions, - GEOS_FMT( "{}: invalid number of values in attribute '{}'", getFullName(), viewKeyStruct::molarWeightsString() ), - InputError ); - - GEOS_THROW_IF_NE_MSG( m_mineralDensities.size(), numKineticReactions, - GEOS_FMT( "{}: invalid number of values in attribute '{}'", getFullName(), viewKeyStruct::mineralDensitiesString() ), - InputError ); -} - void ReactivePorosity::saveConvergedState() const { PorosityBase::saveConvergedState(); diff --git a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp index c36c5b59d39..049019307d3 100644 --- a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp +++ b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp @@ -121,6 +121,10 @@ class ReactivePorosity : public PorosityBase public: ReactivePorosity( string const & name, Group * const parent ); + virtual std::unique_ptr< ConstitutiveBase > + deliverClone( string const & name, + dataRepository::Group * const parent ) const override; + virtual void allocateConstitutiveData( dataRepository::Group & parent, localIndex const numConstitutivePointsPerParentIndex ) override; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index b2b6fa71ee0..58334ad0269 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -27,6 +27,7 @@ #include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp" #include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp" #include "constitutive/fluid/reactivefluid/ReactiveFluidSelector.hpp" +#include "constitutive/solid/CoupledSolidBase.hpp" #include "finiteVolume/FluxApproximationBase.hpp" #include "mesh/DomainPartition.hpp" #include "physicsSolvers/LogLevelsInfo.hpp" @@ -158,6 +159,41 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) } ); } +void SinglePhaseReactiveTransport::validateConstitutiveModels( DomainPartition & domain ) const +{ + GEOS_MARK_FUNCTION; + + SinglePhaseBase::validateConstitutiveModels( domain ); + + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + string const & porosityModelName = getConstitutiveName< PorosityBase >( subRegion ); + + PorosityBase const & porosity = getConstitutiveModel< PorosityBase >( subRegion, porosityModelName ); + + GEOS_THROW_IF( m_isUpdateReactivePorosity && (porosity.getCatalogName() != "ReactivePorosity"), + GEOS_FMT( "SinglePhaseReactiveTransport {}: the reaction porosity update option is enabled in the solver, but the porosity model {} is not for reactive porosity", + getDataContext(), porosity.getDataContext() ), + InputError ); + + if( m_isUpdateReactivePorosity ) + { + ReactivePorosity const & reactivePorosity = getConstitutiveModel< ReactivePorosity >( subRegion, porosityModelName ); + + GEOS_THROW_IF_NE_MSG( reactivePorosity.numKineticReactions(), m_numKineticReactions, + GEOS_FMT( "Mismatch in number of kinetic reactions, check the number of components input in porosity model {}", + reactivePorosity.getDataContext() ), + InputError ); + } + } ); + } ); +} + void SinglePhaseReactiveTransport::setupDofs( DomainPartition const & domain, DofManager & dofManager ) const { diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index 58d32505f60..979ad01f559 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -159,6 +159,12 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase void initializeEquilibriumReaction( ElementSubRegionBase & subRegion ) const; + /** + * @brief Checks constitutive models for consistency + * @param[in] domain the domain partition + */ + virtual void validateConstitutiveModels( DomainPartition & domain ) const override final; + /** * @brief Getter for the number of fluid components (species) * @return the number of components From 8d5f229c7aaa7ef216a983f58c18a761b27d6df6 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Mon, 16 Jun 2025 12:17:08 -0700 Subject: [PATCH 28/66] added source b.c. --- .../fluidFlow/SinglePhaseBase.hpp | 2 +- .../SinglePhaseReactiveTransport.cpp | 537 ++++++++++++------ .../SinglePhaseReactiveTransport.hpp | 17 + 3 files changed, 378 insertions(+), 178 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.hpp index 0b6832ae960..87ff12f39f7 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseBase.hpp @@ -240,7 +240,7 @@ class SinglePhaseBase : public FlowSolverBase * @param localMatrix local system matrix * @param localRhs local system right-hand side vector */ - void + virtual void applySourceFluxBC( 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 58334ad0269..4bca44e7fc4 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -28,6 +28,11 @@ #include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp" #include "constitutive/fluid/reactivefluid/ReactiveFluidSelector.hpp" #include "constitutive/solid/CoupledSolidBase.hpp" +#include "fieldSpecification/FieldSpecificationManager.hpp" +#include "fieldSpecification/LogLevelsInfo.hpp" +#include "fieldSpecification/SourceFluxBoundaryCondition.hpp" +#include "physicsSolvers/fluidFlow/SourceFluxStatistics.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp" #include "finiteVolume/FluxApproximationBase.hpp" #include "mesh/DomainPartition.hpp" #include "physicsSolvers/LogLevelsInfo.hpp" @@ -736,6 +741,16 @@ void SinglePhaseReactiveTransport::initializePostInitialConditionsPreSubGroups() FlowSolverBase::initializeState( domain ); } +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::applyBoundaryConditions( real64 const time_n, real64 const dt, DomainPartition & domain, @@ -748,175 +763,317 @@ void SinglePhaseReactiveTransport::applyBoundaryConditions( real64 const time_n, // apply pressure boundary conditions. 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 flux boundary conditions + applySourceFluxBC( time_n, dt, domain, dofManager, 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 +void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) const { -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."; + 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, + string_array const & ) + { + integer const isThermal = m_isThermal; + integer const numPrimarySpecies = m_numPrimarySpecies; + + fsManager.apply< ElementSubRegionBase, + SourceFluxBoundaryCondition >( time_n + dt, + mesh, + SourceFluxBoundaryCondition::catalogName(), + [&, isThermal, numPrimarySpecies]( SourceFluxBoundaryCondition const & fs, + string const & setName, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) + { + if( m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) + { + globalIndex const numTargetElems = MpiWrapper::sum< globalIndex >( targetSet.size() ); + GEOS_LOG_LEVEL_RANK_0_ON_GROUP( logInfo::BoundaryCondition, + GEOS_FMT( bcLogMessage, + getName(), time_n+dt, fs.getCatalogName(), fs.getName(), + setName, subRegion.getName(), fs.getScale(), numTargetElems ), + fs ); + } + + if( targetSet.size() == 0 ) + { + return; + } + if( !subRegion.hasWrapper( dofKey ) ) + { + GEOS_LOG_LEVEL_BY_RANK_ON_GROUP( logInfo::SourceFluxFailure, + GEOS_FMT( "{}: trying to apply SourceFlux, but its targetSet named '{}' intersects with non-simulated region named '{}'.", + getDataContext(), setName, subRegion.getName() ), + fs ); + 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_n + 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 ) + { + using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid const & fluid = + getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ) ); + + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); + arrayView4d< real64 const, reactivefluid::USD_SPECIES_DC > const dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations = fluid.dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations(); + arrayView2d< real64 const, singlefluid::USD_FLUID > const density = fluid.density(); + arrayView3d< real64 const, constitutive::singlefluid::USD_FLUID_DER > const dDensity = fluid.dDensity(); + arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const enthalpy = fluid.enthalpy(); + arrayView3d< real64 const, constitutive::singlefluid::USD_FLUID_DER > const dEnthalpy = fluid.dEnthalpy(); + + forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, + targetSet, + rankOffset, + ghostRank, + dofNumber, + numPrimarySpecies, + primarySpeciesAggregateConcentration, + dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + density, + dDensity, + enthalpy, + dEnthalpy, + rhsContributionArrayView, + localRhs, + localMatrix, + massProd] GEOS_HOST_DEVICE ( localIndex const a ) + { + singlePhaseReactiveBaseKernels::internal::kernelLaunchSelectorCompSwitch( numPrimarySpecies, [&] ( auto NS ) + { + integer constexpr NUM_SPECIES = NS(); + + // we need to filter out ghosts here, because targetSet may contain them + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + // add the value to the mass balance equation + globalIndex const massRowIndex = dofNumber[ei] - rankOffset; + globalIndex const energyRowIndex = massRowIndex + 1; + globalIndex const speciesRowBeginIndex = massRowIndex + 2; + real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here! + localRhs[massRowIndex] += rhsValue; + massProd += rhsValue; + + // add the value to the energy balance equation and species mass balance equations if the flux is positive (i.e., it's a producer) + if( rhsContributionArrayView[a] > 0.0 ) + { + globalIndex const pressureDofIndex = dofNumber[ei] - rankOffset; + globalIndex const temperatureDofIndex = pressureDofIndex + 1; + + globalIndex dofIndices[2+NUM_SPECIES]{}; + + dofIndices[0] = pressureDofIndex; + dofIndices[1] = temperatureDofIndex; + + for( integer i = 0; i < NUM_SPECIES; ++i ) + { + dofIndices[i+2] = pressureDofIndex + i + 2; + } + + // add the value to the energy balance equation + localRhs[energyRowIndex] += enthalpy[ei][0] * rhsValue; + + real64 jacobianEnergyFlux[2+NUM_SPECIES]{0.0}; + + jacobianEnergyFlux[0] = rhsValue * dEnthalpy[ei][0][DerivOffset::dP]; + jacobianEnergyFlux[1] = rhsValue * dEnthalpy[ei][0][DerivOffset::dT]; + + localMatrix.template addToRow< serialAtomic >( energyRowIndex, + dofIndices, + jacobianEnergyFlux, + 2+NUM_SPECIES ); + + // add the value to the species mass balance equations + for( integer i = 0; i < NUM_SPECIES; ++i ) + { + localRhs[speciesRowBeginIndex + i] += primarySpeciesAggregateConcentration[ei][0][i] / density[ei][0] * rhsValue; + + real64 jacobianSpeciesFlux[2+NUM_SPECIES] = {0.0}; + jacobianSpeciesFlux[0] += -primarySpeciesAggregateConcentration[ei][0][i] * dDensity[ei][0][DerivOffset::dP] / (density[ei][0] * density[ei][0]) * rhsValue; + jacobianSpeciesFlux[1] += -primarySpeciesAggregateConcentration[ei][0][i] * dDensity[ei][0][DerivOffset::dT] / (density[ei][0] * density[ei][0]) * rhsValue; + + for( integer j = 0; j < NUM_SPECIES; ++j ) + { + jacobianSpeciesFlux[j+2] += dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[ei][0][i][j] / density[ei][0] * rhsValue; + } + + localMatrix.template addToRow< serialAtomic >( speciesRowBeginIndex + i, + dofIndices, + jacobianSpeciesFlux, + 2+NUM_SPECIES ); + } + } + } ); + } ); + } + else + { + using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; + reactivefluid::ReactiveCompressibleSinglePhaseFluid const & fluid = + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ) ); + + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); + arrayView4d< real64 const, reactivefluid::USD_SPECIES_DC > const dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations = fluid.dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations(); + arrayView2d< real64 const, singlefluid::USD_FLUID > const density = fluid.density(); + arrayView3d< real64 const, constitutive::singlefluid::USD_FLUID_DER > const dDensity = fluid.dDensity(); + + forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, + targetSet, + rankOffset, + ghostRank, + dofNumber, + numPrimarySpecies, + primarySpeciesAggregateConcentration, + dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + density, + dDensity, + rhsContributionArrayView, + localRhs, + localMatrix, + massProd] GEOS_HOST_DEVICE ( localIndex const a ) + { + singlePhaseReactiveBaseKernels::internal::kernelLaunchSelectorCompSwitch( numPrimarySpecies, [&] ( auto NS ) + { + integer constexpr NUM_SPECIES = NS(); + + // we need to filter out ghosts here, because targetSet may contain them + localIndex const ei = targetSet[a]; + if( ghostRank[ei] >= 0 ) + { + return; + } + + // add the value to the mass balance equation + globalIndex const massRowIndex = dofNumber[ei] - rankOffset; + globalIndex const speciesRowBeginIndex = massRowIndex + 1; + real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here! + localRhs[massRowIndex] += rhsValue; + massProd += rhsValue; + + //add the value to the species mass balance equations if the flux is positive (i.e., it's a producer) + if( rhsContributionArrayView[a] > 0.0 ) + { + globalIndex const pressureDofIndex = dofNumber[ei] - rankOffset; + + globalIndex dofIndices[1+NUM_SPECIES]{}; + + dofIndices[0] = pressureDofIndex; + + for( integer i = 0; i < NUM_SPECIES; ++i ) + { + dofIndices[i+1] = pressureDofIndex + i + 1; + } + + for( integer i = 0; i < NUM_SPECIES; ++i ) + { + localRhs[speciesRowBeginIndex + i] += primarySpeciesAggregateConcentration[ei][0][i] / density[ei][0] * rhsValue; + + real64 jacobian[1+NUM_SPECIES] = {0.0}; + jacobian[0] += -primarySpeciesAggregateConcentration[ei][0][i] * dDensity[ei][0][DerivOffset::dP] / (density[ei][0] * density[ei][0]) * rhsValue; + + for( integer j = 0; j < NUM_SPECIES; ++j ) + { + jacobian[j+1] += dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[ei][0][i][j] / density[ei][0] * rhsValue; + } + + localMatrix.template addToRow< serialAtomic >( speciesRowBeginIndex + i, + dofIndices, + jacobian, + 1+NUM_SPECIES ); + } + } + } ); + } ); + } + + SourceFluxStatsAggregator::forAllFluxStatWrappers( subRegion, fs.getName(), + [&]( SourceFluxStatsAggregator::WrappedStats & wrapper ) + { + // set the new sub-region statistics for this timestep + array1d< real64 > massProdArr{ 1 }; + massProdArr[0] = massProd.get(); + wrapper.gatherTimeStepStats( time_n, dt, massProdArr.toViewConst(), targetSet.size() ); + } ); + } ); + } ); } void SinglePhaseReactiveTransport::applyDirichletBC( real64 const time_n, @@ -935,7 +1092,7 @@ void SinglePhaseReactiveTransport::applyDirichletBC( real64 const time_n, // 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 + // 2. Apply primary species BC (log promary species concentration) 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 @@ -948,7 +1105,7 @@ void SinglePhaseReactiveTransport::applyDirichletBC( real64 const time_n, globalIndex const rankOffset = dofManager.rankOffset(); string const dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() ); - // 4. Apply pressure and log primary species concentration to the system + // 4. Apply pressure to the system fsManager.apply< ElementSubRegionBase >( time_n + dt, mesh, fields::flow::pressure::key(), @@ -962,19 +1119,11 @@ void SinglePhaseReactiveTransport::applyDirichletBC( real64 const time_n, 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]; @@ -995,10 +1144,44 @@ void SinglePhaseReactiveTransport::applyDirichletBC( real64 const time_n, bcPres[ei], pres[ei] ); localRhs[localRow] = rhsValue; + } ); + } ); + + // 5. Apply log primary species concentration to the system + fsManager.apply< ElementSubRegionBase >( time_n + dt, + mesh, + fields::flow::logPrimarySpeciesConcentration::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 ); + + arrayView2d< real64 const, compflow::USD_COMP > const bcLogPrimaryConc = + subRegion.getReference< array2d< real64, compflow::LAYOUT_COMP > >( fields::flow::bcLogPrimarySpeciesConcentration::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; integer const speciesDofBeginIndex = m_isThermal? 2:1; - // 4.2. For each component, apply target global density value + // 5.1. For each component, apply target global density value for( integer is = 0; is < numPrimarySpecies; ++is ) { FieldSpecificationEqual::SpecifyFieldValue( dofIndex + is + speciesDofBeginIndex, @@ -1012,7 +1195,7 @@ void SinglePhaseReactiveTransport::applyDirichletBC( real64 const time_n, } ); } ); - // 5. Apply temperature to the system + // 6. Apply temperature to the system if( m_isThermal ) { fsManager.apply< ElementSubRegionBase >( time_n + dt, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index 979ad01f559..505c2610b5c 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -200,6 +200,23 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) override; + /** + * @brief Apply source flux boundary conditions to the system + * @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 + */ + virtual void + applySourceFluxBC( 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 Function to perform the Application of Dirichlet type BC's * @param time current time From 02f4e5b6256630e94846b97a2ae6b400cefc6a6d Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Thu, 19 Jun 2025 14:47:40 -0700 Subject: [PATCH 29/66] update HPCReact version. --- 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 8f7e7ae4acc..a4384a6f7cf 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 8f7e7ae4accd91427c909b7dacc855916e221ac0 +Subproject commit a4384a6f7cf3fae2a1169547757a5dd36d7cab45 From bf9bf4725d340958866721eb0d5c3aae92626565 Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Thu, 19 Jun 2025 15:47:56 -0700 Subject: [PATCH 30/66] Fixes for new hpcReact branch. --- src/cmake/GeosxOptions.cmake | 2 + .../ReactiveSinglePhaseFluid.hpp | 41 +++++++++++-------- .../SinglePhaseReactiveTransport.cpp | 9 +++- .../SinglePhaseReactiveTransportFields.hpp | 8 ++++ .../reactive/ReactionUpdateKernel.hpp | 5 ++- 5 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/cmake/GeosxOptions.cmake b/src/cmake/GeosxOptions.cmake index c9072b081a4..57f1681a0ca 100644 --- a/src/cmake/GeosxOptions.cmake +++ b/src/cmake/GeosxOptions.cmake @@ -36,6 +36,8 @@ endif() option( ENABLE_PVTPackage "" ON ) +option( ENABLE_HPCREACT "" ON ) + option( ENABLE_UNCRUSTIFY "" ON ) option( ENABLE_XML_UPDATES "" ON ) diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index 228597816b1..d1d9749da1c 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -27,10 +27,11 @@ #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/MixedEquilibriumKineticReactions.hpp" -#include "constitutive/HPCReact/src/reactions/bulkGeneric/SpeciesUtilities.hpp" +#include "constitutive/HPCReact/src/reactions/geochemistry/GeochemicalSystems.hpp" +#include "constitutive/HPCReact/src/reactions/exampleSystems/BulkGeneric.hpp" +#include "constitutive/HPCReact/src/reactions/reactionsSystems/EquilibriumReactions.hpp" +#include "constitutive/HPCReact/src/reactions/reactionsSystems/MixedEquilibriumKineticReactions.hpp" +#include "constitutive/HPCReact/src/reactions/massActions/MassActions.hpp" #include namespace geos @@ -42,7 +43,7 @@ namespace constitutive namespace reactivefluid { -using namespace hpcReact::bulkGeneric; +using namespace hpcReact::reactionsSystems; enum class ChemicalSystemType : integer { @@ -133,7 +134,7 @@ class ReactiveSinglePhaseFluid : public BASE m_params( params ) {} - using EquilibriumReactionsType = hpcReact::bulkGeneric::EquilibriumReactions< real64, integer, localIndex >; + using EquilibriumReactionsType = hpcReact::reactionsSystems::EquilibriumReactions< real64, integer, localIndex >; /** * @brief Get number of elements in this wrapper. @@ -156,11 +157,13 @@ class ReactiveSinglePhaseFluid : public BASE void updateMixedReactionSystem( localIndex const k, real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration ) const; + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & surfaceArea ) const; void computeAggregateConcentrationsAndRates( real64 const pressure, real64 const temperature, arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & surfaceArea, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logSecondarySpeciesConcentration, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & aggregatePrimarySpeciesConcentrations, arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, @@ -193,16 +196,18 @@ class ReactiveSinglePhaseFluid : public BASE }; std::variant< - typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::ultramaficSystemType >, - typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemType >, - typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemAllEquilibriumType >, + typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::geochemistry::ultramaficSystemType >, + typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::geochemistry::carbonateSystemType >, + typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::geochemistry::carbonateSystemAllEquilibriumType >, typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::simpleTestType > > createReactionKernelWrapper() const { + using namespace hpcReact::geochemistry; + using namespace hpcReact::bulkGeneric; switch( m_chemicalSystemType ) { case ChemicalSystemType::ultramafic: - return ReactionKernelWrapper< hpcReact::bulkGeneric::ultramaficSystemType >( m_primarySpeciesAggregateConcentration, + return ReactionKernelWrapper< ultramaficSystemType >( m_primarySpeciesAggregateConcentration, m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, m_secondarySpeciesConcentration, m_kineticReactionRates, @@ -214,7 +219,7 @@ class ReactiveSinglePhaseFluid : public BASE ultramaficSystem ); case ChemicalSystemType::carbonate: - return ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemType >( m_primarySpeciesAggregateConcentration, + return ReactionKernelWrapper< carbonateSystemType >( m_primarySpeciesAggregateConcentration, m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, m_secondarySpeciesConcentration, m_kineticReactionRates, @@ -225,7 +230,7 @@ class ReactiveSinglePhaseFluid : public BASE m_numKineticReactions, carbonateSystem ); case ChemicalSystemType::carbonateAllEquilibrium: - return ReactionKernelWrapper< hpcReact::bulkGeneric::carbonateSystemAllEquilibriumType >( m_primarySpeciesAggregateConcentration, + return ReactionKernelWrapper< carbonateSystemAllEquilibriumType >( m_primarySpeciesAggregateConcentration, m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, m_secondarySpeciesConcentration, m_kineticReactionRates, @@ -236,7 +241,7 @@ class ReactiveSinglePhaseFluid : public BASE m_numKineticReactions, carbonateSystemAllEquilibrium ); default: - return ReactionKernelWrapper< hpcReact::bulkGeneric::simpleTestType >( m_primarySpeciesAggregateConcentration, + return ReactionKernelWrapper< simpleTestType >( m_primarySpeciesAggregateConcentration, m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, m_secondarySpeciesConcentration, m_kineticReactionRates, @@ -333,7 +338,7 @@ enforceEquilibrium( real64 const pressure, EquilibriumReactionsType::enforceEquilibrium_Aggregate( temperature, m_params, logPrimarySpeciesAggregateConcentration, logPrimarySpeciesConcentration ); // 2. We calculate the secondary species concentration - hpcReact::bulkGeneric::calculateLogSecondarySpeciesConcentration< real64, + hpcReact::massActions::calculateLogSecondarySpeciesConcentration< real64, localIndex, localIndex >( m_params, logPrimarySpeciesConcentration, logSecondarySpeciesConcentration ); } @@ -345,7 +350,8 @@ ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >: updateMixedReactionSystem( localIndex const k, real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration ) const + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & surfaceArea ) const { integer const numPrimarySpecies = m_numPrimarySpecies; integer const numSecondarySpecies = m_numSecondarySpecies; @@ -357,6 +363,7 @@ updateMixedReactionSystem( localIndex const k, computeAggregateConcentrationsAndRates( pressure, temperature, logPrimarySpeciesConcentration, + surfaceArea, logSecondarySpeciesConcentration.toSlice(), m_primarySpeciesAggregateConcentration[k][0], m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[k][0], @@ -378,6 +385,7 @@ ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >: computeAggregateConcentrationsAndRates( real64 const pressure, real64 const temperature, arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & surfaceArea, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logSecondarySpeciesConcentration, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & aggregatePrimarySpeciesConcentrations, arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, @@ -392,6 +400,7 @@ computeAggregateConcentrationsAndRates( real64 const pressure, updateMixedSystem( temperature, m_params, logPrimarySpeciesConcentration, + surfaceArea, logSecondarySpeciesConcentration, aggregatePrimarySpeciesConcentrations, dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 4bca44e7fc4..3e76f48b3b3 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -160,6 +160,9 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) subRegion.registerField< kineticReactionMolarIncrements >( getName() ). reference().resizeDimension< 1 >( m_numKineticReactions ); + + subRegion.registerField< surfaceArea >( getName() ). + reference().resizeDimension< 1 >( m_numKineticReactions ); } ); } ); } @@ -618,6 +621,8 @@ void SinglePhaseReactiveTransport::updateMixedReactionSystem( ElementSubRegionBa arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); arrayView1d< real64 const > const temp = subRegion.getField< fields::flow::temperature >(); arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc = subRegion.getField< fields::flow::logPrimarySpeciesConcentration >(); + arrayView2d< real64 const, compflow::USD_COMP > const surfaceArea = subRegion.getField< fields::flow::surfaceArea >(); + if( m_isThermal ) { @@ -626,7 +631,7 @@ void SinglePhaseReactiveTransport::updateMixedReactionSystem( ElementSubRegionBa constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) { - singlePhaseReactiveBaseKernels::MixedSystemReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc ); + singlePhaseReactiveBaseKernels::MixedSystemReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc, surfaceArea ); } ); } else @@ -636,7 +641,7 @@ void SinglePhaseReactiveTransport::updateMixedReactionSystem( ElementSubRegionBa constitutive::constitutiveUpdatePassThru( fluid, [&]( auto & castedFluid ) { - singlePhaseReactiveBaseKernels::MixedSystemReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc ); + singlePhaseReactiveBaseKernels::MixedSystemReactionUpdateKernel::launch( castedFluid, pres, temp, logPrimaryConc, surfaceArea ); } ); } } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp index 432696405af..b19a169c1a4 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp @@ -91,6 +91,14 @@ DECLARE_FIELD( dMobility_dLogPrimaryConc, NO_WRITE, "Derivative of fluid mobility with respect to log of primary species concentration" ); +DECLARE_FIELD( surfaceArea, + "surfaceArea", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "Surface Area for surface reactions." ); + } } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp index 7cba2caf3a7..aaaede6d88e 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp @@ -59,13 +59,14 @@ struct MixedSystemReactionUpdateKernel static void launch( REACTIVE_FLUID const & fluid, arrayView1d< real64 const > const & pres, arrayView1d< real64 const > const & temp, - arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc ) + arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc, + arrayView2d< real64 const, compflow::USD_COMP > const surfaceArea ) { std::visit( [&]( auto const reactionWrapper ) { forAll< parallelDevicePolicy<> >( reactionWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) { - reactionWrapper.updateMixedReactionSystem( k, pres[k], temp[k], logPrimaryConc[k] ); + reactionWrapper.updateMixedReactionSystem( k, pres[k], temp[k], logPrimaryConc[k], surfaceArea[k] ); } ); }, fluid.createReactionKernelWrapper()); } From 5615c3945b451bb6164787a832ffba5349800b97 Mon Sep 17 00:00:00 2001 From: Matteo Cusini Date: Fri, 20 Jun 2025 10:38:17 -0700 Subject: [PATCH 31/66] latest hpcReact commit. --- 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 a4384a6f7cf..e901104c584 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit a4384a6f7cf3fae2a1169547757a5dd36d7cab45 +Subproject commit e901104c58465c954a983526d85563e6195d7542 From bf6a9e009522ca76ecf49f998a6ebd9f6b20a36d Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Fri, 20 Jun 2025 12:38:20 -0700 Subject: [PATCH 32/66] to update number of primary after adding the surface reaction in HPCReact --- .../fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index 8805d997138..f1fb7fb3e8f 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -82,7 +82,7 @@ void ReactiveSinglePhaseFluid< BASE >::postInputInitialization() break; case ChemicalSystemType::carbonate: - m_numPrimarySpecies = 8; + m_numPrimarySpecies = 7; m_numSecondarySpecies = 10; m_numKineticReactions = 1; break; From 6ed29d03144a0a32051680f93a8d165d09e3a095 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Sat, 28 Jun 2025 10:49:33 -0700 Subject: [PATCH 33/66] added surfaceArea update --- .../constitutive/solid/ReactiveSolid.hpp | 36 +++++ .../solid/porosity/ReactivePorosity.cpp | 21 ++- .../solid/porosity/ReactivePorosity.hpp | 27 +++- .../SinglePhaseReactiveTransport.cpp | 55 ++++++- .../SinglePhaseReactiveTransport.hpp | 6 + .../SinglePhaseReactiveTransportFields.hpp | 10 +- .../testSinglePhaseReactiveTransport.cpp | 151 +++++------------- 7 files changed, 182 insertions(+), 124 deletions(-) diff --git a/src/coreComponents/constitutive/solid/ReactiveSolid.hpp b/src/coreComponents/constitutive/solid/ReactiveSolid.hpp index 5a72ba2a52d..ee7396f27e5 100644 --- a/src/coreComponents/constitutive/solid/ReactiveSolid.hpp +++ b/src/coreComponents/constitutive/solid/ReactiveSolid.hpp @@ -64,6 +64,24 @@ class ReactiveSolidUpdates : public CoupledSolidUpdates< NullModel, PORO_TYPE, P real64 const porosity = m_porosityUpdate.getPorosity( k, q ); m_permUpdate.updateFromPressureAndPorosity( k, q, pressure, porosity ); } + + GEOS_HOST_DEVICE + void updateSurfaceArea( localIndex const k, + localIndex const q, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & initialSurfaceArea, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & surfaceArea ) const + { + real64 const porosity = m_porosityUpdate.getPorosity( k, q ); + real64 const initialPorosity = m_porosityUpdate.getInitialPorosity( k, q ); + + for( integer r=0; r < initialSurfaceArea.size(); ++r ) + { + real64 const volumeFraction_r = m_porosityUpdate.getVolumeFractionForMineral( k, q, r ); + real64 const initialVolumeFraction_r = m_porosityUpdate.getInitialVolumeFractionForMineral( k, q, r ); + surfaceArea[r] = initialSurfaceArea[r] * pow( volumeFraction_r / initialVolumeFraction_r, 2.0/3.0 ) + * pow( porosity / initialPorosity, 2.0/3.0 ); + } + } private: using CoupledSolidUpdates< NullModel, ReactivePorosity, PERM_TYPE >::m_solidUpdate; @@ -121,6 +139,24 @@ class ReactiveSolid : public CoupledSolid< NullModel, PORO_TYPE, PERM_TYPE > */ virtual string getCatalogName() const override { return catalogName(); } + /* + * @brief get the volume fractions. + * return a constant arrayView3d to the new volume fractions + */ + arrayView3d< real64 const > const getVolumeFractions() const + { + return getPorosityModel().getVolumeFractions(); + } + + /* + * @brief get the initial volume fractions. + * return a constant arrayView1d to the initial volume fractions + */ + arrayView1d< real64 const > const getInitialVolumeFractions() const + { + return getPorosityModel().getInitialVolumeFractions(); + } + /** * @brief Create a instantiation of the ReactiveSolidUpdates class diff --git a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp index c9e46cccd27..241b43d08b7 100644 --- a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp +++ b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp @@ -30,8 +30,13 @@ namespace constitutive ReactivePorosity::ReactivePorosity( string const & name, Group * const parent ): PorosityBase( name, parent ) { - registerWrapper( viewKeyStruct::initialVolumeFractionsString(), &m_initialVolumeFractions ). + registerWrapper( viewKeyStruct::defaultInitialVolumeFractionsString(), &m_defaultInitialVolumeFractions ). setInputFlag( InputFlags::REQUIRED ). + setDescription( "Default initial volume fractions" ); + + registerWrapper( viewKeyStruct::initialVolumeFractionsString(), &m_initialVolumeFractions ). + setApplyDefaultValue( 0.0 ). + setPlotLevel( PlotLevel::LEVEL_0 ). setDescription( "Initial volume fractions" ); registerWrapper( viewKeyStruct::volumeFractionsString(), &m_volumeFractions ). @@ -68,17 +73,17 @@ void ReactivePorosity::postInputInitialization() { PorosityBase::postInputInitialization(); - GEOS_THROW_IF_NE_MSG( m_molarWeights.size(), m_initialVolumeFractions.size(), + GEOS_THROW_IF_NE_MSG( m_molarWeights.size(), m_defaultInitialVolumeFractions.size(), GEOS_FMT( "{}: mismatch in number of components in porosity model attribute '{}' and '{}", getFullName(), viewKeyStruct::molarWeightsString(), viewKeyStruct::initialVolumeFractionsString() ), InputError ); - GEOS_THROW_IF_NE_MSG( m_mineralDensities.size(), m_initialVolumeFractions.size(), + GEOS_THROW_IF_NE_MSG( m_mineralDensities.size(), m_defaultInitialVolumeFractions.size(), GEOS_FMT( "{}: mismatch in number of components in porosity model attribute '{}' and '{}", getFullName(), viewKeyStruct::mineralDensitiesString(), viewKeyStruct::initialVolumeFractionsString() ), InputError ); - m_numKineticReactions = m_initialVolumeFractions.size(); + m_numKineticReactions = m_defaultInitialVolumeFractions.size(); } void ReactivePorosity::allocateConstitutiveData( dataRepository::Group & parent, @@ -94,6 +99,7 @@ void ReactivePorosity::resizeFields( localIndex const size, localIndex const num { integer const numKineticReactions = this->numKineticReactions(); + m_initialVolumeFractions.resize( size, numPts, numKineticReactions ); m_volumeFractions.resize( size, numPts, numKineticReactions ); m_volumeFractions_n.resize( size, numPts, numKineticReactions ); } @@ -106,7 +112,7 @@ void ReactivePorosity::saveConvergedState() const } void ReactivePorosity::initializeState() const -{ +{ integer const numKineticReactions = this->numKineticReactions(); for( localIndex ei = 0; ei < m_newPorosity.size( 0 ); ++ei ) @@ -125,8 +131,9 @@ void ReactivePorosity::initializeState() const { for( integer r = 0; r < numKineticReactions; ++r ) { - m_volumeFractions[ei][q][r] = m_initialVolumeFractions[r]; - m_volumeFractions_n[ei][q][r] = m_initialVolumeFractions[r]; + m_volumeFractions[ei][q][r] = m_defaultInitialVolumeFractions[r]; + m_initialVolumeFractions[ei][q][r] = m_defaultInitialVolumeFractions[r]; + m_volumeFractions_n[ei][q][r] = m_defaultInitialVolumeFractions[r]; } } } diff --git a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp index 049019307d3..cbc9c4016ff 100644 --- a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp +++ b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp @@ -40,6 +40,7 @@ class ReactivePorosityUpdates : public PorosityBaseUpdates arrayView2d< real64 const > const & initialPorosity, arrayView1d< real64 const > const & referencePorosity, arrayView3d< real64, reactivefluid::USD_SPECIES > const & volumeFractions, + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const & initialVolumeFractions, arrayView3d< real64 const, reactivefluid::USD_SPECIES > const & volumeFractions_n, integer const numKineticReactions, arrayView1d< real64 const > const & molarWeights, @@ -51,6 +52,7 @@ class ReactivePorosityUpdates : public PorosityBaseUpdates initialPorosity, referencePorosity ), m_volumeFractions( volumeFractions ), + m_initialVolumeFractions( initialVolumeFractions ), m_volumeFractions_n( volumeFractions_n ), m_numKineticReactions( numKineticReactions ), m_molarWeights( molarWeights ), @@ -105,9 +107,28 @@ class ReactivePorosityUpdates : public PorosityBaseUpdates m_mineralDensities ); } + GEOS_HOST_DEVICE + inline + real64 getVolumeFractionForMineral( localIndex const k, + localIndex const q, + localIndex const r ) const + { + return m_volumeFractions[k][q][r]; + } + + GEOS_HOST_DEVICE + inline + real64 getInitialVolumeFractionForMineral( localIndex const k, + localIndex const q, + localIndex const r ) const + { + return m_initialVolumeFractions[k][q][r]; + } + protected: arrayView3d< real64, reactivefluid::USD_SPECIES > m_volumeFractions; + arrayView3d< real64 const, reactivefluid::USD_SPECIES > m_initialVolumeFractions; arrayView3d< real64 const, reactivefluid::USD_SPECIES > const m_volumeFractions_n; integer const m_numKineticReactions; @@ -140,6 +161,7 @@ class ReactivePorosity : public PorosityBase struct viewKeyStruct : public PorosityBase::viewKeyStruct { + static constexpr char const * defaultInitialVolumeFractionsString() { return "defaultInitialVolumeFractions"; } static constexpr char const * initialVolumeFractionsString() { return "initialVolumeFractions"; } static constexpr char const * volumeFractionsString() { return "volumeFractions"; } static constexpr char const * volumeFractions_nString() { return "volumeFractions_n"; } @@ -147,6 +169,7 @@ class ReactivePorosity : public PorosityBase static constexpr char const * mineralDensitiesString() { return "mineralDensities"; } } viewKeys; + using KernelWrapper = ReactivePorosityUpdates; /** @@ -162,6 +185,7 @@ class ReactivePorosity : public PorosityBase m_initialPorosity, m_referencePorosity, m_volumeFractions, + m_initialVolumeFractions, m_volumeFractions_n, m_numKineticReactions, m_molarWeights, @@ -174,9 +198,10 @@ class ReactivePorosity : public PorosityBase virtual void resizeFields( localIndex const size, localIndex const numPts ); - array1d< real64 > m_initialVolumeFractions; + array1d< real64 > m_defaultInitialVolumeFractions; array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_volumeFractions; + array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_initialVolumeFractions; array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_volumeFractions_n; integer m_numKineticReactions; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 3e76f48b3b3..1ab176c6c4f 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -28,6 +28,7 @@ #include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp" #include "constitutive/fluid/reactivefluid/ReactiveFluidSelector.hpp" #include "constitutive/solid/CoupledSolidBase.hpp" +#include "constitutive/solid/ReactiveSolid.hpp" #include "fieldSpecification/FieldSpecificationManager.hpp" #include "fieldSpecification/LogLevelsInfo.hpp" #include "fieldSpecification/SourceFluxBoundaryCondition.hpp" @@ -52,7 +53,8 @@ SinglePhaseReactiveTransport::SinglePhaseReactiveTransport( const string & name, m_numPrimarySpecies( 0 ), m_numKineticReactions( 0 ), m_hasDiffusion( 0 ), - m_isUpdateReactivePorosity( 0 ) + m_isUpdateReactivePorosity( 0 ), + m_isUpdateSurfaceArea( 0 ) { // To add modeling parameters we want to add here @@ -60,6 +62,11 @@ SinglePhaseReactiveTransport::SinglePhaseReactiveTransport( const string & name, setApplyDefaultValue( 0 ). setInputFlag( InputFlags::OPTIONAL ). setDescription( "Flag indicating whether use the reactive porosity or not" ); + + this->registerWrapper( viewKeyStruct::isUpdateSurfaceAreaString(), &m_isUpdateSurfaceArea ). + setApplyDefaultValue( 0 ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Flag indicating whether to update the surface area or not" ); } // TODO: we need to update the class of ReactiveSingleFluid to be consistent with the chemistry module!!! @@ -162,7 +169,10 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) reference().resizeDimension< 1 >( m_numKineticReactions ); subRegion.registerField< surfaceArea >( getName() ). - reference().resizeDimension< 1 >( m_numKineticReactions ); + reference().resizeDimension< 1 >( m_numKineticReactions ); + + subRegion.registerField< initialSurfaceArea >( getName() ). + reference().resizeDimension< 1 >( m_numKineticReactions ); } ); } ); } @@ -618,12 +628,13 @@ void SinglePhaseReactiveTransport::updateMixedReactionSystem( ElementSubRegionBa { GEOS_MARK_FUNCTION; + updateSurfaceArea( subRegion ); + arrayView1d< real64 const > const pres = subRegion.getField< fields::flow::pressure >(); arrayView1d< real64 const > const temp = subRegion.getField< fields::flow::temperature >(); arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc = subRegion.getField< fields::flow::logPrimarySpeciesConcentration >(); arrayView2d< real64 const, compflow::USD_COMP > const surfaceArea = subRegion.getField< fields::flow::surfaceArea >(); - if( m_isThermal ) { reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & fluid = @@ -646,6 +657,44 @@ void SinglePhaseReactiveTransport::updateMixedReactionSystem( ElementSubRegionBa } } +void SinglePhaseReactiveTransport::updateSurfaceArea( ElementSubRegionBase & subRegion ) const +{ + GEOS_MARK_FUNCTION; + + arrayView2d< real64 const, compflow::USD_COMP > const initialSurfaceArea = subRegion.getField< fields::flow::initialSurfaceArea >(); + arrayView2d< real64, compflow::USD_COMP > const surfaceArea = subRegion.getField< fields::flow::surfaceArea >(); + + if( m_isUpdateReactivePorosity && m_isUpdateSurfaceArea ) + { + string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); + CoupledSolidBase & porousSolid = subRegion.template getConstitutiveModel< CoupledSolidBase >( solidName ); + + constitutive::ConstitutivePassThru< ReactiveSolidBase >::execute( porousSolid, [=, &subRegion] ( auto & castedPorousSolid ) + { + typename TYPEOFREF( castedPorousSolid ) ::KernelWrapper porousWrapper = castedPorousSolid.createKernelUpdates(); + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_DEVICE ( localIndex const k ) + { + for( localIndex q = 0; q < porousWrapper.numGauss(); ++q ) + { + porousWrapper.updateSurfaceArea( k, q, + initialSurfaceArea[k], + surfaceArea[k] ); + } + } ); + } ); + } + else + { + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) + { + for( integer ir = 0; ir < m_numKineticReactions; ++ir ) + { + surfaceArea[ei][ir] = initialSurfaceArea[ei][ir]; + } + } ); + } +} + void SinglePhaseReactiveTransport::initializeFluidState( MeshLevel & mesh, string_array const & regionNames ) { mesh.getElemManager().forElementSubRegions< CellElementSubRegion, SurfaceElementSubRegion >( regionNames, [&]( localIndex const, diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index 505c2610b5c..7b47ab22ba5 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -144,6 +144,8 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase void updateMixedReactionSystem( ElementSubRegionBase & subRegion ) const; + void updateSurfaceArea( ElementSubRegionBase & subRegion ) const; + void updateSpeciesAmount( ElementSubRegionBase & subRegion ) const; void updateKineticReactionMolarIncrements( real64 const dt, @@ -279,6 +281,7 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase { static constexpr char const * diffusionNamesString() { return "diffusionNames"; } static constexpr char const * isUpdateReactivePorosityString() { return "isUpdateReactivePorosity"; } + static constexpr char const * isUpdateSurfaceAreaString() { return "isUpdateSurfaceArea"; } }; protected: @@ -297,6 +300,9 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase /// flag to determine whether or not to use the reactive porosity integer m_isUpdateReactivePorosity; + + /// flag to determine whether or not to update the surface area + integer m_isUpdateSurfaceArea; }; template< typename OBJECT_TYPE > diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp index b19a169c1a4..98d9e158330 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp @@ -97,7 +97,15 @@ DECLARE_FIELD( surfaceArea, 0, LEVEL_0, WRITE_AND_READ, - "Surface Area for surface reactions." ); + "Surface area for surface reactions." ); + +DECLARE_FIELD( initialSurfaceArea, + "initialSurfaceArea", + array2dLayoutComp, + 0, + LEVEL_0, + WRITE_AND_READ, + "Initial surface area for surface reactions." ); } diff --git a/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp b/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp index 18374afa629..306ab221e98 100644 --- a/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/unitTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp @@ -122,205 +122,132 @@ char const * xmlInputCarbonate = fieldName="pressure" scale="1.2e6" /> + + + scale="1.585e-7"/> + scale="8.293e-3"/> + scale="2.171e-3"/> + scale="1.666e-6"/> + scale="2.821e-5"/> - - + scale="1.605e-3"/> + component="6" + scale="7.817e-4"/> + scale="-19.21448423"/> + scale="-2.73216432"/> - + scale="-4.77653747"/> + + scale="-14.28117504"/> + scale="-10.47763277"/> - - - - - - - - - - + scale="-6.43480025"/> - - - - - - - - + scale="-7.15404368"/> )xml"; From 84bb91d7d154d1289eddb57e0ee3faefa3586376 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Sat, 28 Jun 2025 10:50:16 -0700 Subject: [PATCH 34/66] updated 1D tests --- ...tionCarbonateSystemPorosityUpdate_base.xml | 162 ++++++++ ...tionCarbonateSystemPorosityUpdate_main.xml | 86 ++++ .../mixedReactionCarbonateSystem_base.xml | 153 +++++++ ...actionCarbonateSystem_initialAggregate.xml | 133 ++++++ .../mixedReactionCarbonateSystem_logConc.xml | 62 +++ .../mixedReactionCarbonateSystem_main.xml | 77 ++++ .../mixedReactionCarbonSystem.xml | 340 ---------------- .../mixedReactionThermalCarbonSystem.xml | 378 ------------------ 8 files changed, 673 insertions(+), 718 deletions(-) create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_base.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_base.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialAggregate.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_logConc.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml delete mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionCarbonSystem.xml delete mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionThermalCarbonSystem.xml diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_base.xml new file mode 100644 index 00000000000..fd414cd5ba2 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_base.xml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml new file mode 100644 index 00000000000..4cfa9acb9f8 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_base.xml new file mode 100644 index 00000000000..7ef7360e004 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_base.xml @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialAggregate.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialAggregate.xml new file mode 100644 index 00000000000..767b9387978 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialAggregate.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_logConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_logConc.xml new file mode 100644 index 00000000000..da291b97da0 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_logConc.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml new file mode 100644 index 00000000000..17fb267acdc --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionCarbonSystem.xml b/inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionCarbonSystem.xml deleted file mode 100644 index 484dd0405b7..00000000000 --- a/inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionCarbonSystem.xml +++ /dev/null @@ -1,340 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionThermalCarbonSystem.xml b/inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionThermalCarbonSystem.xml deleted file mode 100644 index 3160112fd45..00000000000 --- a/inputFiles/singlePhaseFlow/reactiveTransport/mixedReactionThermalCarbonSystem.xml +++ /dev/null @@ -1,378 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From c3f0c381e804f2f25c2c98ef973a743b547692ad Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Mon, 14 Jul 2025 17:16:29 -0700 Subject: [PATCH 35/66] enabled mobile aggregate concentrations --- src/coreComponents/constitutive/HPCReact | 2 +- .../reactivefluid/ReactiveFluidFields.hpp | 16 +++ .../ReactiveSinglePhaseFluid.cpp | 8 +- .../ReactiveSinglePhaseFluid.hpp | 128 +++++++++++------- .../SinglePhaseReactiveTransport.cpp | 24 ++++ .../SinglePhaseReactiveTransport.hpp | 5 + .../reactive/FluxComputeKernel.hpp | 60 ++++---- .../reactive/ThermalFluxComputeKernel.hpp | 30 ++-- 8 files changed, 186 insertions(+), 87 deletions(-) diff --git a/src/coreComponents/constitutive/HPCReact b/src/coreComponents/constitutive/HPCReact index e901104c584..877df19cc3c 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit e901104c58465c954a983526d85563e6195d7542 +Subproject commit 877df19cc3cb7378e3bdbdc60820f647ec8bb297 diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp index 0b4e3226e1c..7db479800de 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp @@ -59,6 +59,14 @@ DECLARE_FIELD( primarySpeciesAggregateConcentration_n, WRITE_AND_READ, "primarySpeciesAggregateConcentration at the previous timestep" ); +DECLARE_FIELD( primarySpeciesMobileAggregateConcentration, + "primarySpeciesMobileAggregateConcentration", + array3dLayoutSpecies, + 1e-16, + LEVEL_0, + WRITE_AND_READ, + "primarySpeciesMobileAggregateConcentration" ); + DECLARE_FIELD( dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, "dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations", array4dLayoutSpecies_dC, @@ -67,6 +75,14 @@ DECLARE_FIELD( dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentra WRITE_AND_READ, "Deivatives of primarySpeciesAggregateConcentration w.r.t log primary species concentration" ); +DECLARE_FIELD( dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + "dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations", + array4dLayoutSpecies_dC, + 0, + LEVEL_0, + WRITE_AND_READ, + "Deivatives of primarySpeciesMobileAggregateConcentration w.r.t log primary species concentration" ); + DECLARE_FIELD( secondarySpeciesConcentration, "secondarySpeciesConcentration", array3dLayoutSpecies, diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index f1fb7fb3e8f..664c0b99938 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -46,7 +46,9 @@ ReactiveSinglePhaseFluid( string const & name, Group * const parent ): 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::primarySpeciesMobileAggregateConcentration{}, &m_primarySpeciesMobileAggregateConcentration ); this->registerField( fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations{}, &m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations ); + this->registerField( fields::reactivefluid::dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations{}, &m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations ); this->registerField( fields::reactivefluid::kineticReactionRates{}, &m_kineticReactionRates ); this->registerField( fields::reactivefluid::aggregateSpeciesRates{}, &m_aggregateSpeciesRates ); this->registerField( fields::reactivefluid::dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations{}, &m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ); @@ -94,8 +96,8 @@ void ReactiveSinglePhaseFluid< BASE >::postInputInitialization() break; default: - m_numPrimarySpecies = 3; - m_numSecondarySpecies = 2; + m_numPrimarySpecies = 5; + m_numSecondarySpecies = 7; m_numKineticReactions = 0; break; } @@ -119,7 +121,9 @@ void ReactiveSinglePhaseFluid< BASE >::resizeFields( localIndex const size, loca m_secondarySpeciesConcentration.resize( size, numPts, numSecondarySpecies ); m_primarySpeciesAggregateConcentration.resize( size, numPts, numPrimarySpecies ); m_primarySpeciesAggregateConcentration_n.resize( size, numPts, numPrimarySpecies ); + m_primarySpeciesMobileAggregateConcentration.resize( size, numPts, numPrimarySpecies ); m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations.resize( size, numPts, numPrimarySpecies, numPrimarySpecies ); + m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations.resize( size, numPts, numPrimarySpecies, numPrimarySpecies ); m_kineticReactionRates.resize( size, numPts, numKineticReactions ); m_aggregateSpeciesRates.resize( size, numPts, numPrimarySpecies ); m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations.resize( size, numPts, numPrimarySpecies, numPrimarySpecies ); diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index d1d9749da1c..50bddd38646 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -29,6 +29,7 @@ #include "constitutive/HPCReact/src/reactions/geochemistry/GeochemicalSystems.hpp" #include "constitutive/HPCReact/src/reactions/exampleSystems/BulkGeneric.hpp" +#include "constitutive/HPCReact/src/reactions/exampleSystems/MoMasBenchmark.hpp" #include "constitutive/HPCReact/src/reactions/reactionsSystems/EquilibriumReactions.hpp" #include "constitutive/HPCReact/src/reactions/reactionsSystems/MixedEquilibriumKineticReactions.hpp" #include "constitutive/HPCReact/src/reactions/massActions/MassActions.hpp" @@ -50,7 +51,7 @@ enum class ChemicalSystemType : integer carbonate, carbonateAllEquilibrium, ultramafic, - simple + momas }; template< typename BASE > @@ -82,9 +83,15 @@ class ReactiveSinglePhaseFluid : public BASE arrayView3d< real64 const, reactivefluid::USD_SPECIES > primarySpeciesAggregateConcentration_n() const { return m_primarySpeciesAggregateConcentration_n; } + arrayView3d< real64 const, reactivefluid::USD_SPECIES > primarySpeciesMobileAggregateConcentration() const + { return m_primarySpeciesMobileAggregateConcentration; } + arrayView4d< real64 const, reactivefluid::USD_SPECIES_DC > dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations() const { return m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations; } + arrayView4d< real64 const, reactivefluid::USD_SPECIES_DC > dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations() const + { return m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations; } + arrayView3d< real64 const, reactivefluid::USD_SPECIES > secondarySpeciesConcentration() const { return m_secondarySpeciesConcentration; } @@ -113,7 +120,9 @@ class ReactiveSinglePhaseFluid : public BASE public: ReactionKernelWrapper( arrayView3d< real64, reactivefluid::USD_SPECIES > const & primarySpeciesAggregateConcentration, + arrayView3d< real64, reactivefluid::USD_SPECIES > const & primarySpeciesMobileAggregateConcentration, arrayView4d< real64, reactivefluid::USD_SPECIES_DC > const & dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + arrayView4d< real64, reactivefluid::USD_SPECIES_DC > const & dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, arrayView3d< real64, reactivefluid::USD_SPECIES > const & secondarySpeciesConcentration, arrayView3d< real64, reactivefluid::USD_SPECIES > const & kineticReactionRates, arrayView3d< real64, reactivefluid::USD_SPECIES > const & aggregateSpeciesRates, @@ -126,7 +135,9 @@ class ReactiveSinglePhaseFluid : public BASE m_numSecondarySpecies( numSecondarySpecies ), m_numKineticReactions( numKineticReactions ), m_primarySpeciesAggregateConcentration( primarySpeciesAggregateConcentration ), + m_primarySpeciesMobileAggregateConcentration( primarySpeciesMobileAggregateConcentration ), m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations( dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations ), + m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations( dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations ), m_secondarySpeciesConcentration( secondarySpeciesConcentration ), m_kineticReactionRates( kineticReactionRates ), m_aggregateSpeciesRates( aggregateSpeciesRates ), @@ -165,8 +176,10 @@ class ReactiveSinglePhaseFluid : public BASE arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & surfaceArea, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logSecondarySpeciesConcentration, - arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & aggregatePrimarySpeciesConcentrations, - arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesAggregateConcentration, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesMobileAggregateConcentration, + arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & reactionRates, arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dReactionRates_dLogPrimarySpeciesConcentrations, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & aggregateSpeciesRates, @@ -182,8 +195,12 @@ class ReactiveSinglePhaseFluid : public BASE arrayView3d< real64, reactivefluid::USD_SPECIES > m_primarySpeciesAggregateConcentration; + arrayView3d< real64, reactivefluid::USD_SPECIES > m_primarySpeciesMobileAggregateConcentration; + arrayView4d< real64, reactivefluid::USD_SPECIES_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations; + arrayView4d< real64, reactivefluid::USD_SPECIES_DC > m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations; + arrayView3d< real64, reactivefluid::USD_SPECIES > m_secondarySpeciesConcentration; arrayView3d< real64, reactivefluid::USD_SPECIES > m_kineticReactionRates; @@ -199,58 +216,67 @@ class ReactiveSinglePhaseFluid : public BASE typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::geochemistry::ultramaficSystemType >, typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::geochemistry::carbonateSystemType >, typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::geochemistry::carbonateSystemAllEquilibriumType >, - typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::bulkGeneric::simpleTestType > > + typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::MomMasBenchmark::simpleSystemType > > createReactionKernelWrapper() const { using namespace hpcReact::geochemistry; + using namespace hpcReact::MomMasBenchmark; using namespace hpcReact::bulkGeneric; switch( m_chemicalSystemType ) { case ChemicalSystemType::ultramafic: return ReactionKernelWrapper< ultramaficSystemType >( m_primarySpeciesAggregateConcentration, - m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, - m_secondarySpeciesConcentration, - m_kineticReactionRates, - m_aggregateSpeciesRates, - m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, - m_numPrimarySpecies, - m_numSecondarySpecies, - m_numKineticReactions, - ultramaficSystem ); + m_primarySpeciesMobileAggregateConcentration, + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_secondarySpeciesConcentration, + m_kineticReactionRates, + m_aggregateSpeciesRates, + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, + m_numPrimarySpecies, + m_numSecondarySpecies, + m_numKineticReactions, + ultramaficSystem ); case ChemicalSystemType::carbonate: return ReactionKernelWrapper< carbonateSystemType >( m_primarySpeciesAggregateConcentration, - m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, - m_secondarySpeciesConcentration, - m_kineticReactionRates, - m_aggregateSpeciesRates, - m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, - m_numPrimarySpecies, - m_numSecondarySpecies, - m_numKineticReactions, - carbonateSystem ); + m_primarySpeciesMobileAggregateConcentration, + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_secondarySpeciesConcentration, + m_kineticReactionRates, + m_aggregateSpeciesRates, + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, + m_numPrimarySpecies, + m_numSecondarySpecies, + m_numKineticReactions, + carbonateSystem ); case ChemicalSystemType::carbonateAllEquilibrium: return ReactionKernelWrapper< carbonateSystemAllEquilibriumType >( m_primarySpeciesAggregateConcentration, - m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, - m_secondarySpeciesConcentration, - m_kineticReactionRates, - m_aggregateSpeciesRates, - m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, - m_numPrimarySpecies, - m_numSecondarySpecies, - m_numKineticReactions, - carbonateSystemAllEquilibrium ); + m_primarySpeciesMobileAggregateConcentration, + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_secondarySpeciesConcentration, + m_kineticReactionRates, + m_aggregateSpeciesRates, + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, + m_numPrimarySpecies, + m_numSecondarySpecies, + m_numKineticReactions, + carbonateSystemAllEquilibrium ); default: - return ReactionKernelWrapper< simpleTestType >( m_primarySpeciesAggregateConcentration, - m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, - m_secondarySpeciesConcentration, - m_kineticReactionRates, - m_aggregateSpeciesRates, - m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, - m_numPrimarySpecies, - m_numSecondarySpecies, - m_numKineticReactions, - simpleTestRateParams ); + return ReactionKernelWrapper< simpleSystemType >( m_primarySpeciesAggregateConcentration, + m_primarySpeciesMobileAggregateConcentration, + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_secondarySpeciesConcentration, + m_kineticReactionRates, + m_aggregateSpeciesRates, + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, + m_numPrimarySpecies, + m_numSecondarySpecies, + m_numKineticReactions, + simpleSystemParams ); } } @@ -277,8 +303,12 @@ class ReactiveSinglePhaseFluid : public BASE array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_primarySpeciesAggregateConcentration_n; + array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_primarySpeciesMobileAggregateConcentration; + array4d< real64, constitutive::reactivefluid::LAYOUT_SPECIES_DC > m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations; + array4d< real64, constitutive::reactivefluid::LAYOUT_SPECIES_DC > m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations; + array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_kineticReactionRates; array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_aggregateSpeciesRates; @@ -366,7 +396,9 @@ updateMixedReactionSystem( localIndex const k, surfaceArea, logSecondarySpeciesConcentration.toSlice(), m_primarySpeciesAggregateConcentration[k][0], + m_primarySpeciesMobileAggregateConcentration[k][0], m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[k][0], + m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations[k][0], m_kineticReactionRates[k][0], dReactionRates_dLogPrimarySpeciesConcentrations.toSlice(), m_aggregateSpeciesRates[k][0], @@ -387,8 +419,10 @@ computeAggregateConcentrationsAndRates( real64 const pressure, arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & surfaceArea, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logSecondarySpeciesConcentration, - arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & aggregatePrimarySpeciesConcentrations, - arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesAggregateConcentration, + arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesMobileAggregateConcentration, + arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & reactionRates, arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dReactionRates_dLogPrimarySpeciesConcentrations, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & aggregateSpeciesRates, @@ -402,8 +436,10 @@ computeAggregateConcentrationsAndRates( real64 const pressure, logPrimarySpeciesConcentration, surfaceArea, logSecondarySpeciesConcentration, - aggregatePrimarySpeciesConcentrations, - dAggregatePrimarySpeciesConcentrations_dLogPrimarySpeciesConcentrations, + primarySpeciesAggregateConcentration, + primarySpeciesMobileAggregateConcentration, + dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, reactionRates, dReactionRates_dLogPrimarySpeciesConcentrations, aggregateSpeciesRates, @@ -414,7 +450,7 @@ ENUM_STRINGS( ChemicalSystemType, "carbonate", "carbonateAllEquilibrium", "ultramafic", - "simple" ); + "momas" ); } // namespace reactivefluid diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 1ab176c6c4f..734860723df 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -67,6 +67,11 @@ SinglePhaseReactiveTransport::SinglePhaseReactiveTransport( const string & name, setApplyDefaultValue( 0 ). setInputFlag( InputFlags::OPTIONAL ). setDescription( "Flag indicating whether to update the surface area or not" ); + + this->registerWrapper( viewKeyStruct::immobilePrimarySpeciesIndicesString(), &m_immobilePrimarySpeciesIndices ). + setApplyDefaultValue( { } ). + setInputFlag( InputFlags::OPTIONAL ). + setDescription( "Array to store the indices of immobile species. Default is {}, which indicates no immobile species." ); } // TODO: we need to update the class of ReactiveSingleFluid to be consistent with the chemistry module!!! @@ -404,6 +409,23 @@ void SinglePhaseReactiveTransport::assembleFluxTerms( real64 const dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) { + array1d< integer > mobilePrimarySpeciesFlags; + mobilePrimarySpeciesFlags.resize( m_numPrimarySpecies ); + + for( integer i=0; i 0 ) + { + for( integer i = 0; i < m_immobilePrimarySpeciesIndices.size(); ++i ) + { + localIndex const immobileSpeciesIndex = m_immobilePrimarySpeciesIndices[i]; + mobilePrimarySpeciesFlags[immobileSpeciesIndex] = 0; + } + } + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel const & mesh, string_array const & ) @@ -423,6 +445,7 @@ void SinglePhaseReactiveTransport::assembleFluxTerms( real64 const dt, thermalSinglePhaseReactiveFVMKernels:: FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, m_hasDiffusion, + mobilePrimarySpeciesFlags.toViewConst(), dofManager.rankOffset(), dofKey, getName(), @@ -437,6 +460,7 @@ void SinglePhaseReactiveTransport::assembleFluxTerms( real64 const dt, singlePhaseReactiveFVMKernels:: FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, m_hasDiffusion, + mobilePrimarySpeciesFlags.toViewConst(), dofManager.rankOffset(), dofKey, getName(), diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index 7b47ab22ba5..f9e5cc3a476 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -282,6 +282,7 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase static constexpr char const * diffusionNamesString() { return "diffusionNames"; } static constexpr char const * isUpdateReactivePorosityString() { return "isUpdateReactivePorosity"; } static constexpr char const * isUpdateSurfaceAreaString() { return "isUpdateSurfaceArea"; } + static constexpr char const * immobilePrimarySpeciesIndicesString() { return "immobilePrimarySpeciesIndices"; } }; protected: @@ -303,6 +304,10 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase /// flag to determine whether or not to update the surface area integer m_isUpdateSurfaceArea; + + /// array to store the indices of immobile primary species + array1d< integer > m_immobilePrimarySpeciesIndices; + }; 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 bf887c55fd3..49c6d4e18c0 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp @@ -96,8 +96,8 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E using ReactiveSinglePhaseFluidAccessors = StencilMaterialAccessors< constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE >, - fields::reactivefluid::primarySpeciesAggregateConcentration, - fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations >; + fields::reactivefluid::primarySpeciesMobileAggregateConcentration, + fields::reactivefluid::dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations >; using DiffusionAccessors = StencilMaterialAccessors< constitutive::DiffusionBase, @@ -121,6 +121,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E * @param[in] diffusionAccessors * @param[in] porosityAccessors * @param[in] hasDiffusion the flag to turn on diffusion calculation + * @param[in] mobilePrimarySpeciesFlags the array of flags to indicate mobile primary species * @param[in] dt time step size * @param[inout] localMatrix the local CRS matrix * @param[inout] localRhs the local right-hand side vector @@ -136,6 +137,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E DiffusionAccessors const & diffusionAccessors, PorosityAccessors const & porosityAccessors, integer const & hasDiffusion, + arrayView1d< integer const > const & mobilePrimarySpeciesFlags, real64 const & dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) @@ -150,12 +152,13 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E 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_dLogPrimarySpeciesConcentrations {} ) ), + m_primarySpeciesMobileAggregateConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::primarySpeciesMobileAggregateConcentration {} ) ), + m_dPrimarySpeciesMobileAggregateConc_dLogPrimaryConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations {} ) ), 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 ) + m_hasDiffusion( hasDiffusion ), + m_mobilePrimarySpeciesFlags( mobilePrimarySpeciesFlags ) {} /** @@ -245,7 +248,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E // 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][0][is]; + real64 const aggregateConc_i = m_primarySpeciesMobileAggregateConc[er_up][esr_up][ei_up][0][is]; speciesFlux[is] = aggregateConc_i / fluidDens_up * fluxVal; for( integer ke = 0; ke < numFluxSupportPoints; ++ke ) @@ -257,7 +260,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E for( integer js = 0; js < numSpecies; ++js ) { - real64 const dAggregateConc_i_dLogConc_j = m_dPrimarySpeciesAggregateConc_dLogPrimaryConc[er_up][esr_up][ei_up][0][is][js]; + real64 const dAggregateConc_i_dLogConc_j = m_dPrimarySpeciesMobileAggregateConc_dLogPrimaryConc[er_up][esr_up][ei_up][0][is][js]; dSpeciesFlux_dLogConc[k_up][is][js] += dAggregateConc_i_dLogConc_j / fluidDens_up * fluxVal; } } @@ -268,20 +271,20 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E 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]; + stack.localFlux[eqIndex0] += m_dt * speciesFlux[is] * m_mobilePrimarySpeciesFlags[is]; + stack.localFlux[eqIndex1] -= m_dt * speciesFlux[is] * m_mobilePrimarySpeciesFlags[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]; + stack.localFluxJacobian[eqIndex0][localDofIndexPres] += m_dt * dSpeciesFlux_dP[ke][is] * m_mobilePrimarySpeciesFlags[is]; + stack.localFluxJacobian[eqIndex1][localDofIndexPres] -= m_dt * dSpeciesFlux_dP[ke][is] * m_mobilePrimarySpeciesFlags[is]; for( integer js = 0; js < numSpecies; ++js ) { 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]; + stack.localFluxJacobian[eqIndex0][localDofIndexSpecies] += m_dt * dSpeciesFlux_dLogConc[ke][is][js] * m_mobilePrimarySpeciesFlags[is]; + stack.localFluxJacobian[eqIndex1][localDofIndexSpecies] -= m_dt * dSpeciesFlux_dLogConc[ke][is][js] * m_mobilePrimarySpeciesFlags[is]; } } } @@ -339,7 +342,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E //***** calculation of flux ***** // loop over primary species for( integer is = 0; is < numSpecies; ++is ) - { + { // real64 dSpeciesGrad_i_dP[numFluxSupportPoints]{}; // Turn on if speciesGrad is pressure-dependent real64 dSpeciesGrad_i_dLogConc[numFluxSupportPoints][numSpecies]{}; @@ -350,13 +353,13 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E localIndex const esr = sesri[ke]; localIndex const ei = sei[ke]; - real64 const aggregateConc_i = m_primarySpeciesAggregateConc[er][esr][ei][0][is]; + real64 const aggregateConc_i = m_primarySpeciesMobileAggregateConc[er][esr][ei][0][is]; speciesGrad[is] += diffusionTrans[ke] * aggregateConc_i; for( integer js = 0; js < numSpecies; ++js ) { - real64 const dAggregateConc_i_dLogConc_j = m_dPrimarySpeciesAggregateConc_dLogPrimaryConc[er][esr][ei][0][is][js]; + real64 const dAggregateConc_i_dLogConc_j = m_dPrimarySpeciesMobileAggregateConc_dLogPrimaryConc[er][esr][ei][0][is][js]; dSpeciesGrad_i_dLogConc[ke][js] += diffusionTrans[ke] * dAggregateConc_i_dLogConc_j; } @@ -385,20 +388,20 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E 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]; + stack.localFlux[eqIndex0] += m_dt * diffusionFlux[is] * m_mobilePrimarySpeciesFlags[is]; + stack.localFlux[eqIndex1] -= m_dt * diffusionFlux[is] * m_mobilePrimarySpeciesFlags[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]; + // stack.localFluxJacobian[eqIndex0][localDofIndexPres] += m_dt * dDiffusionFlux_dP[ke][is] * m_mobilePrimarySpeciesFlags[is]; + // stack.localFluxJacobian[eqIndex1][localDofIndexPres] -= m_dt * dDiffusionFlux_dP[ke][is] * m_mobilePrimarySpeciesFlags[is]; for( integer js = 0; js < numSpecies; ++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]; + stack.localFluxJacobian[eqIndex0][localDofIndexSpecies] += m_dt * dDiffusionFlux_dLogConc[ke][is][js] * m_mobilePrimarySpeciesFlags[is]; + stack.localFluxJacobian[eqIndex1][localDofIndexSpecies] -= m_dt * dDiffusionFlux_dLogConc[ke][is][js] * m_mobilePrimarySpeciesFlags[is]; } } @@ -479,10 +482,10 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E ElementViewConst< arrayView2d< real64 const, compflow::USD_FLUID_DC > > const m_dMob_dLogPrimaryConc; /// Views on primary species aggregate concentration - ElementViewConst< arrayView3d< real64 const, constitutive::reactivefluid::USD_SPECIES > > const m_primarySpeciesAggregateConc; + ElementViewConst< arrayView3d< real64 const, constitutive::reactivefluid::USD_SPECIES > > const m_primarySpeciesMobileAggregateConc; - /// Views on the derivative of primary species aggregate concentration wrt log of primary concentration - ElementViewConst< arrayView4d< real64 const, constitutive::reactivefluid::USD_SPECIES_DC > > const m_dPrimarySpeciesAggregateConc_dLogPrimaryConc; + /// Views on the derivative of primary species mobile aggregate concentration wrt log of primary concentration + ElementViewConst< arrayView4d< real64 const, constitutive::reactivefluid::USD_SPECIES_DC > > const m_dPrimarySpeciesMobileAggregateConc_dLogPrimaryConc; /// Views on diffusivity ElementViewConst< arrayView3d< real64 const > > const m_diffusivity; @@ -493,6 +496,9 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E /// Flag of adding the diffusion term integer const m_hasDiffusion; + + /// Array of flags to indicate mobile primary species + arrayView1d< integer const > const m_mobilePrimarySpeciesFlags; }; /** @@ -508,6 +514,7 @@ class FluxComputeKernelFactory * @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] mobilePrimarySpeciesFlags the array of flags to indicate mobile 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) @@ -521,6 +528,7 @@ class FluxComputeKernelFactory static void createAndLaunch( integer const numSpecies, integer const hasDiffusion, + arrayView1d< integer const > const mobilePrimarySpeciesFlags, globalIndex const rankOffset, string const & dofKey, string const & solverName, @@ -551,7 +559,7 @@ class FluxComputeKernelFactory KernelType kernel( rankOffset, stencilWrapper, dofNumberAccessor, flowAccessors, reactiveFlowAccessors, fluidAccessors, reactiveFluidAccessors, - permAccessors, diffusionAccessors, porosityAccessors, hasDiffusion, + permAccessors, diffusionAccessors, porosityAccessors, hasDiffusion, mobilePrimarySpeciesFlags, dt, localMatrix, localRhs ); KernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); } ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp index ef2c9171663..41ac478a001 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp @@ -85,8 +85,9 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne using Base::m_seri; using Base::m_sesri; using Base::m_sei; - using Base::m_primarySpeciesAggregateConc; + using Base::m_primarySpeciesMobileAggregateConc; using Base::m_referencePorosity; + using Base::m_mobilePrimarySpeciesFlags; using ThermalSinglePhaseFlowAccessors = StencilAccessors< fields::flow::temperature >; @@ -118,6 +119,7 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne * @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] mobilePrimarySpeciesFlags the array of flags to indicate mobile primary species * @param[in] dt time step size * @param[inout] localMatrix the local CRS matrix * @param[inout] localRhs the local right-hand side vector @@ -136,6 +138,7 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne PorosityAccessors const & porosityAccessors, ThermalConductivityAccessors const & thermalConductivityAccessors, integer const & hasDiffusion, + arrayView1d< integer const > const & mobilePrimarySpeciesFlags, real64 const & dt, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) @@ -150,13 +153,14 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne diffusionAccessors, porosityAccessors, hasDiffusion, + mobilePrimarySpeciesFlags, 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_dPrimarySpeciesMobileAggregateConcentration_dTemp( fluid.dPrimarySpeciesMobileAggregateConcentration_dTemp() ), m_thermalConductivity( thermalConductivityAccessors.get( fields::thermalconductivity::effectiveConductivity {} ) ), m_dThermalCond_dT( thermalConductivityAccessors.get( fields::thermalconductivity::dEffectiveConductivity_dT {} ) ) {} @@ -322,10 +326,10 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne // 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][0][is]; + { + real64 const aggregateConc_i = m_primarySpeciesMobileAggregateConc[er_up][esr_up][ei_up][0][is]; - // real64 const dAggregateConc_i_dTemp = m_dPrimarySpeciesAggregateConcentration_dTemp[er_up][esr_up][ei_up][is]; + // real64 const dAggregateConc_i_dTemp = m_dPrimarySpeciesMobileAggregateConcentration_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); @@ -346,8 +350,8 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne { 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]; + stack.localFluxJacobian[eqIndex0][localDofIndexTemp] += m_dt * dSpeciesFlux_dT[ke][is] * m_mobilePrimarySpeciesFlags[is]; + stack.localFluxJacobian[eqIndex1][localDofIndexTemp] -= m_dt * dSpeciesFlux_dT[ke][is] * m_mobilePrimarySpeciesFlags[is]; } } @@ -482,9 +486,9 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne localIndex const ei = sei[ke]; // dSpeciesGrad_dT[ke] += stack.diffusionTransmissibility[connectionIndex][ke] - // * m_dPrimarySpeciesAggregateConcentration_dTemp[er][esr][ei][is]; + // * m_dPrimarySpeciesMobileAggregateConcentration_dTemp[er][esr][ei][is]; - dSpeciesGrad_dT[ke] += stack.dDiffusionTrans_dT[connectionIndex][ke] * m_primarySpeciesAggregateConc[er][esr][ei][0][is]; + dSpeciesGrad_dT[ke] += stack.dDiffusionTrans_dT[connectionIndex][ke] * m_primarySpeciesMobileAggregateConc[er][esr][ei][0][is]; } for( integer ke = 0; ke < numFluxSupportPoints; ke++ ) @@ -503,8 +507,8 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne 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]; + stack.localFluxJacobian[eqIndex0][localDofIndexTemp] += m_dt * dDiffusionFlux_dT[ke] * m_mobilePrimarySpeciesFlags[is]; + stack.localFluxJacobian[eqIndex1][localDofIndexTemp] -= m_dt * dDiffusionFlux_dT[ke] * m_mobilePrimarySpeciesFlags[is]; } } ); } @@ -568,6 +572,7 @@ class FluxComputeKernelFactory * @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] mobilePrimarySpeciesFlags the array of flags to indicate mobile 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) @@ -581,6 +586,7 @@ class FluxComputeKernelFactory static void createAndLaunch( integer const numSpecies, integer const hasDiffusion, + arrayView1d< integer const > const mobilePrimarySpeciesFlags, globalIndex const rankOffset, string const & dofKey, string const & solverName, @@ -615,7 +621,7 @@ class FluxComputeKernelFactory KernelType kernel( rankOffset, stencilWrapper, dofNumberAccessor, flowAccessors, reactiveFlowAccessors, thermalFlowAccessors, fluidAccessors, reactiveFluidAccessors, thermalFluidAccessors, permAccessors, diffusionAccessors, porosityAccessors, thermalConductivityAccessors, - hasDiffusion, dt, localMatrix, localRhs ); + hasDiffusion, mobilePrimarySpeciesFlags, dt, localMatrix, localRhs ); KernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); } ); } From 31e887f44b25dbdc309de1253aa7af953ca605a0 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Tue, 15 Jul 2025 11:57:49 -0700 Subject: [PATCH 36/66] initial attempts for the MoMaS --- .../MoMaSBenchmark/MoMaS_base.xml | 174 ++++++++++++++++++ .../MoMaSBenchmark/MoMaS_initialAggregate.xml | 97 ++++++++++ .../MoMaSBenchmark/MoMaS_logConc.xml | 46 +++++ .../MoMaSBenchmark/MoMaS_main.xml | 74 ++++++++ .../MoMaSSmoke/MoMaS_base.xml | 126 +++++++++++++ .../MoMaSSmoke/MoMaS_initialAggregate.xml | 51 +++++ .../MoMaSSmoke/MoMaS_logConc.xml | 46 +++++ .../MoMaSSmoke/MoMaS_main.xml | 57 ++++++ .../reactivefluid/ReactiveFluidFields.hpp | 2 +- .../SinglePhaseReactiveTransportFields.hpp | 6 +- 10 files changed, 675 insertions(+), 4 deletions(-) create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialAggregate.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_logConc.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_main.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialAggregate.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_logConc.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml new file mode 100644 index 00000000000..4ed707e5614 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialAggregate.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialAggregate.xml new file mode 100644 index 00000000000..249667cb646 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialAggregate.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_logConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_logConc.xml new file mode 100644 index 00000000000..b3036eeba6a --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_logConc.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_main.xml new file mode 100644 index 00000000000..d950220ee75 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_main.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml new file mode 100644 index 00000000000..dd60f254c84 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialAggregate.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialAggregate.xml new file mode 100644 index 00000000000..ca468612058 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialAggregate.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_logConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_logConc.xml new file mode 100644 index 00000000000..a8b191176dc --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_logConc.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml new file mode 100644 index 00000000000..7c39735055d --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp index 7db479800de..f596a86558b 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp @@ -95,7 +95,7 @@ DECLARE_FIELD( kineticReactionRates, "kineticReactionRates", array3dLayoutSpecies, 0, - LEVEL_0, + NOPLOT, WRITE_AND_READ, "kineticReactionRates" ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp index 98d9e158330..eb4262aae2a 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp @@ -79,7 +79,7 @@ DECLARE_FIELD( kineticReactionMolarIncrements, "kineticReactionMolarIncrements", array2dLayoutComp, 0, - LEVEL_0, + NOPLOT, WRITE_AND_READ, "Molar increment in the current timestep for kinetic reactions" ); @@ -95,7 +95,7 @@ DECLARE_FIELD( surfaceArea, "surfaceArea", array2dLayoutComp, 0, - LEVEL_0, + NOPLOT, WRITE_AND_READ, "Surface area for surface reactions." ); @@ -103,7 +103,7 @@ DECLARE_FIELD( initialSurfaceArea, "initialSurfaceArea", array2dLayoutComp, 0, - LEVEL_0, + NOPLOT, WRITE_AND_READ, "Initial surface area for surface reactions." ); From 6f7c4bf21daf9616b3ac9a410aed27735491fe6a Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Tue, 5 Aug 2025 16:37:24 -0700 Subject: [PATCH 37/66] HPCReact updated --- 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 877df19cc3c..9bddcd452d9 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 877df19cc3cb7378e3bdbdc60820f647ec8bb297 +Subproject commit 9bddcd452d90fcf4de9ab7f5e3d7911850b9973c From fd8fc41c8d1608ec9b96e64f7654f890378da892 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Tue, 5 Aug 2025 16:53:34 -0700 Subject: [PATCH 38/66] changed to use new enforce equilibrium function and updated xmls --- ...tionCarbonateSystemPorosityUpdate_main.xml | 1 + ...ReactionCarbonateSystem_initialLogConc.xml | 133 ++++++++++++++++ .../mixedReactionCarbonateSystem_main.xml | 1 + .../MoMaSBenchmark/MoMaS_base.xml | 65 ++++++-- .../MoMaSBenchmark/MoMaS_initialAggregate.xml | 58 ++++++- .../MoMaSBenchmark/MoMaS_initialLogConc.xml | 143 ++++++++++++++++++ .../MoMaSBenchmark/MoMaS_logConc.xml | 28 ++-- .../MoMaSBenchmark/MoMaS_main.xml | 46 +++--- .../MoMaSSmoke/MoMaS_base.xml | 56 ++++--- .../MoMaSSmoke/MoMaS_initialAggregate.xml | 52 ++++++- .../MoMaSSmoke/MoMaS_initialLogConc.xml | 97 ++++++++++++ .../MoMaSSmoke/MoMaS_logConc.xml | 30 ++-- .../MoMaSSmoke/MoMaS_main.xml | 24 ++- .../ReactiveSinglePhaseFluid.hpp | 18 +-- 14 files changed, 637 insertions(+), 115 deletions(-) create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialLogConc.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialLogConc.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialLogConc.xml diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml index 4cfa9acb9f8..6506610e585 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml @@ -6,6 +6,7 @@ + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialLogConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialLogConc.xml new file mode 100644 index 00000000000..88f98093984 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialLogConc.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml index 17fb267acdc..cc667d5cd02 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml @@ -6,6 +6,7 @@ + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml index 4ed707e5614..bca991d9eef 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml @@ -6,13 +6,13 @@ @@ -33,14 +33,19 @@ name="Region1" cellBlocks="{ * }" materialList="{ water, rock, diffusion }"/> --> + + @@ -97,6 +102,14 @@ + + + + + + @@ -138,17 +167,22 @@ + + @@ -163,6 +197,11 @@ sources="{ /Tasks/logPrimarySpeciesMediumACollection2 }" filename="logPrimarySpeciesMediumAHistory2"/> + + + scale="1e-3"/> + scale="-2.0"/> + scale="1e-3"/> + scale="1e-3"/> + scale="-2.0"/> + scale="1e-3"/> + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialLogConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialLogConc.xml new file mode 100644 index 00000000000..a789a72d174 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialLogConc.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_logConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_logConc.xml index b3036eeba6a..adb33481542 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_logConc.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_logConc.xml @@ -5,42 +5,42 @@ + scale="-1.4206052082"/> + scale="-1.4204810515"/> + scale="-82.1595397322"/> + scale="-19.6464329266"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_main.xml index d950220ee75..fb27e810e36 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_main.xml @@ -5,69 +5,73 @@ + + cellBlockNames="{ cb-0_0_0, cb-1_0_0, cb-2_0_0, cb-3_0_0, cb-4_0_0 }"/> - - + xMin="{ 2.099, -0.01, -0.01 }" + xMax="{ 2.111, 1.01, 1.01 }"/> + maxTime="10"> + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml index dd60f254c84..6c7f5ce9919 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml @@ -6,12 +6,12 @@ --> + + + @@ -62,7 +68,7 @@ name="rockPorosity" defaultReferencePorosity="0.25" referencePressure="0.0" - compressibility="1e-10"/> + compressibility="0.0"/> + + + + - + setNames="{ all }" + objectPath="ElementRegions/Source" + scale="-5.5"/> - + scale="1.0e6"/> - + - + filename="logPrimarySpeciesMediumAHistory"/> --> + scale="1e-3"/> + scale="-2.0"/> + scale="1e-3"/> + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialLogConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialLogConc.xml new file mode 100644 index 00000000000..d709c7f15a9 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialLogConc.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_logConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_logConc.xml index a8b191176dc..adb33481542 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_logConc.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_logConc.xml @@ -5,42 +5,42 @@ + scale="-1.2039728043"/> + scale="-1.4206052082"/> + scale="-1.4204810515"/> + scale="-82.1595397322"/> + scale="-19.6464329266"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml index 7c39735055d..efe5d1ae0b7 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml @@ -4,49 +4,45 @@ - + + + cellBlockNames="{ cb-0_0_0, cb-1_0_0, cb-2_0_0 }"/> - - + xMin="{ 1.989, -0.01, -0.01 }" + xMax="{ 2.01, 1.01, 1.01 }"/> + maxTime="10"> - + target="/Outputs/logPrimarySpeciesMediumAHistoryOutput"/> --> const & logPrimarySpeciesConcentration ) const { - integer const numPrimarySpecies = m_numPrimarySpecies; integer const numSecondarySpecies = m_numSecondarySpecies; - stackArray1d< real64, 10 > logPrimarySpeciesAggregateConcentration( numPrimarySpecies ); - - for( integer i=0; i < numPrimarySpecies; ++i ) - { - logPrimarySpeciesAggregateConcentration[i] = LvArray::math::log( m_primarySpeciesAggregateConcentration[k][0][i] ); - } - - stackArray1d< real64, 20 > logSecondarySpeciesConcentration( numSecondarySpecies ); + stackArray1d< real64, MAX_NUM_SPECIES > logSecondarySpeciesConcentration( numSecondarySpecies ); - enforceEquilibrium( pressure, temperature, logPrimarySpeciesAggregateConcentration.toSliceConst(), logPrimarySpeciesConcentration, logSecondarySpeciesConcentration.toSlice() ); + enforceEquilibrium( pressure, temperature, m_primarySpeciesAggregateConcentration[k][0], logPrimarySpeciesConcentration, logSecondarySpeciesConcentration.toSlice() ); for( integer i=0; i < numSecondarySpecies; ++i ) { @@ -359,13 +351,15 @@ inline void ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >:: enforceEquilibrium( real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesAggregateConcentration, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & targetPrimarySpeciesAggregateConcentration, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logSecondarySpeciesConcentration ) const { GEOS_UNUSED_VAR( pressure ); + + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration0 = logPrimarySpeciesConcentration; // 1. We enforce equilibrium - EquilibriumReactionsType::enforceEquilibrium_Aggregate( temperature, m_params, logPrimarySpeciesAggregateConcentration, logPrimarySpeciesConcentration ); + EquilibriumReactionsType::enforceEquilibrium_Aggregate( temperature, m_params, targetPrimarySpeciesAggregateConcentration, logPrimarySpeciesConcentration0, logPrimarySpeciesConcentration ); // 2. We calculate the secondary species concentration hpcReact::massActions::calculateLogSecondarySpeciesConcentration< real64, From 163cddce4ee1075301bac9867ab6263ce1b455bb Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Tue, 12 Aug 2025 11:15:07 -0700 Subject: [PATCH 39/66] fixed build with HPCReact --- src/coreComponents/constitutive/CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index 8e98c44bd21..d64e9b6e6cc 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -121,10 +121,8 @@ set( constitutive_headers fluid/multifluid/compositional/parameters/PressureTemperatureCoordinates.hpp fluid/multifluid/compositional/CompositionalMultiphaseFluid.hpp fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.hpp - 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 @@ -274,7 +272,6 @@ set( constitutive_sources fluid/multifluid/compositional/parameters/PressureTemperatureCoordinates.cpp fluid/multifluid/compositional/CompositionalMultiphaseFluid.cpp fluid/multifluid/compositional/CompositionalMultiphaseFluidUpdates.cpp - fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp fluid/singlefluid/CompressibleSinglePhaseFluid.cpp fluid/singlefluid/ParticleFluid.cpp fluid/singlefluid/ParticleFluidBase.cpp @@ -354,6 +351,11 @@ if( ENABLE_PVTPackage ) endif() if (ENABLE_HPCREACT) + set( constitutive_headers + ${constitutive_headers} + fluid/reactivefluid/ReactiveFluidSelector.hpp + ) + set( constitutive_headers ${constitutive_headers} fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp From e4845445a27d22b0320111eb708021f032bd774b Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Wed, 13 Aug 2025 10:53:55 -0700 Subject: [PATCH 40/66] fix for CUDA build --- .../fluid/reactivefluid/ReactiveFluidLayouts.hpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp index d4cee0efa4b..5949d33e9ab 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp @@ -72,19 +72,14 @@ struct DerivativeOffsetC< NC, 0 > #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 species variable array array layout +using LAYOUT_SPECIES = RAJA::PERM_JKI; +/// Constitutive model species derivative of species variable array layout +using LAYOUT_SPECIES_DC = RAJA::PERM_JKLI; /// Constitutive model fluid property array layout using LAYOUT_FLUID = RAJA::PERM_JI; -/// Constitutive model fluid property compositional derivative array layout +/// Constitutive model fluid property species derivative array layout using LAYOUT_FLUID_DC = RAJA::PERM_JKI; #else From d29bfa239e76f63ef62976d19abe784a7c65fa3f Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Wed, 13 Aug 2025 13:10:43 -0700 Subject: [PATCH 41/66] fixed b.c. for momas and clean up xmls. --- ...tionCarbonateSystemPorosityUpdate_main.xml | 2 - .../mixedReactionCarbonateSystem_main.xml | 2 - .../MoMaSBenchmark/MoMaS_base.xml | 1 + .../MoMaSBenchmark/MoMaS_initialLogConc.xml | 46 ------------------- .../MoMaSSmoke/MoMaS_initialLogConc.xml | 45 ------------------ .../MoMaSSmoke/MoMaS_main.xml | 4 +- 6 files changed, 3 insertions(+), 97 deletions(-) diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml index 6506610e585..f72a7fa371a 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml @@ -1,7 +1,5 @@ - - diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml index cc667d5cd02..afe71dad376 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml @@ -1,7 +1,5 @@ - - diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml index bca991d9eef..50a95ec3892 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml @@ -13,6 +13,7 @@ diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialLogConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialLogConc.xml index a789a72d174..c5779e62959 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialLogConc.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialLogConc.xml @@ -93,51 +93,5 @@ fieldName="logPrimarySpeciesConcentration" component="4" scale="2.302585093"/> - - - - - - - - - - - diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialLogConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialLogConc.xml index d709c7f15a9..d86540e727e 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialLogConc.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialLogConc.xml @@ -48,50 +48,5 @@ component="4" scale="0.0"/> - - - - - - - - - - diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml index efe5d1ae0b7..d0465f58805 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml @@ -29,7 +29,7 @@ + maxTime="1"> From 24c12dd62905d2c21ba63797e0e799c972159edf Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Wed, 13 Aug 2025 13:10:56 -0700 Subject: [PATCH 42/66] change in 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 9bddcd452d9..3a687e52f64 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 9bddcd452d90fcf4de9ab7f5e3d7911850b9973c +Subproject commit 3a687e52f6489ac322246c83a3488a76edbed683 From 25dca544ac3fe8d498a9030bd5d5bac00b827036 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Thu, 14 Aug 2025 17:35:16 -0700 Subject: [PATCH 43/66] try to solve some compile errors --- src/coreComponents/constitutive/HPCReact | 2 +- .../ReactiveSinglePhaseFluid.hpp | 62 ++++++++++++------- .../constitutive/solid/ReactiveSolid.hpp | 6 +- .../solid/porosity/ReactivePorosity.hpp | 4 +- .../SinglePhaseReactiveTransport.cpp | 54 ++++++++++------ 5 files changed, 82 insertions(+), 46 deletions(-) diff --git a/src/coreComponents/constitutive/HPCReact b/src/coreComponents/constitutive/HPCReact index 3a687e52f64..6d0282aa944 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 3a687e52f6489ac322246c83a3488a76edbed683 +Subproject commit 6d0282aa944e8fb2efbe0abe8fd1acf5e2e645a1 diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index 4b1c4c6596a..0b6d10be396 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -153,35 +153,39 @@ class ReactiveSinglePhaseFluid : public BASE */ GEOS_HOST_DEVICE localIndex numElems() const { return m_secondarySpeciesConcentration.size( 0 ); } - + + GEOS_HOST_DEVICE void updateEquilibriumReaction( localIndex const k, real64 const pressure, real64 const temperature, - arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration ) const; - + arraySlice1d< real64, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration ) const; + + GEOS_HOST_DEVICE void enforceEquilibrium( real64 const pressure, real64 const temperature, arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesTotalConcentration, - arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesConcentration, - arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & secondarySpeciesConcentration ) const; - + arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, + arraySlice1d< real64 > const & secondarySpeciesConcentration ) const; + + GEOS_HOST_DEVICE void updateMixedReactionSystem( localIndex const k, real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & surfaceArea ) const; + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & surfaceArea ) const; + GEOS_HOST_DEVICE void computeAggregateConcentrationsAndRates( real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & surfaceArea, - arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logSecondarySpeciesConcentration, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & surfaceArea, + arraySlice1d< real64 > const & logSecondarySpeciesConcentration, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesAggregateConcentration, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesMobileAggregateConcentration, arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & reactionRates, - arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dReactionRates_dLogPrimarySpeciesConcentrations, + arraySlice2d< real64 > const & dReactionRates_dLogPrimarySpeciesConcentrations, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & aggregateSpeciesRates, arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ) const; @@ -325,6 +329,7 @@ using ReactiveThermalCompressibleSinglePhaseFluid = ReactiveSinglePhaseFluid< Th template< typename BASE > template< typename REACTION_PARAMS_TYPE > +GEOS_HOST_DEVICE inline void ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >:: updateEquilibriumReaction( localIndex const k, @@ -347,19 +352,30 @@ updateEquilibriumReaction( localIndex const k, template< typename BASE > template< typename REACTION_PARAMS_TYPE > +GEOS_HOST_DEVICE inline void ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >:: enforceEquilibrium( real64 const pressure, real64 const temperature, arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & targetPrimarySpeciesAggregateConcentration, - arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, - arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logSecondarySpeciesConcentration ) const + arraySlice1d< real64, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64 > const & logSecondarySpeciesConcentration ) const { GEOS_UNUSED_VAR( pressure ); - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration0 = logPrimarySpeciesConcentration; + integer const numPrimarySpecies = m_numPrimarySpecies; + + stackArray1d< real64, MAX_NUM_SPECIES > logPrimarySpeciesConcentration0( numPrimarySpecies ); + stackArray1d< real64, MAX_NUM_SPECIES > targetPrimarySpeciesAggregateConc( numPrimarySpecies ); + + for( integer i=0; i < numPrimarySpecies; ++i ) + { + targetPrimarySpeciesAggregateConc[i] = targetPrimarySpeciesAggregateConcentration[i]; + logPrimarySpeciesConcentration0[i] = logPrimarySpeciesConcentration[i]; + } + // 1. We enforce equilibrium - EquilibriumReactionsType::enforceEquilibrium_Aggregate( temperature, m_params, targetPrimarySpeciesAggregateConcentration, logPrimarySpeciesConcentration0, logPrimarySpeciesConcentration ); + EquilibriumReactionsType::enforceEquilibrium_Aggregate( temperature, m_params, targetPrimarySpeciesAggregateConc, logPrimarySpeciesConcentration0, logPrimarySpeciesConcentration ); // 2. We calculate the secondary species concentration hpcReact::massActions::calculateLogSecondarySpeciesConcentration< real64, @@ -369,13 +385,14 @@ enforceEquilibrium( real64 const pressure, template< typename BASE > template< typename REACTION_PARAMS_TYPE > +GEOS_HOST_DEVICE inline void ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >:: updateMixedReactionSystem( localIndex const k, real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & surfaceArea ) const + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & surfaceArea ) const { integer const numPrimarySpecies = m_numPrimarySpecies; integer const numSecondarySpecies = m_numSecondarySpecies; @@ -406,19 +423,20 @@ updateMixedReactionSystem( localIndex const k, template< typename BASE > template< typename REACTION_PARAMS_TYPE > +GEOS_HOST_DEVICE inline void ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >:: computeAggregateConcentrationsAndRates( real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & logPrimarySpeciesConcentration, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & surfaceArea, - arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & logSecondarySpeciesConcentration, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & surfaceArea, + arraySlice1d< real64 > const & logSecondarySpeciesConcentration, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesAggregateConcentration, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesMobileAggregateConcentration, arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & reactionRates, - arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dReactionRates_dLogPrimarySpeciesConcentrations, + arraySlice2d< real64 > const & dReactionRates_dLogPrimarySpeciesConcentrations, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & aggregateSpeciesRates, arraySlice2d< real64, reactivefluid::USD_SPECIES_DC - 2 > const & dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ) const { diff --git a/src/coreComponents/constitutive/solid/ReactiveSolid.hpp b/src/coreComponents/constitutive/solid/ReactiveSolid.hpp index ee7396f27e5..19f8d4dabd9 100644 --- a/src/coreComponents/constitutive/solid/ReactiveSolid.hpp +++ b/src/coreComponents/constitutive/solid/ReactiveSolid.hpp @@ -58,7 +58,7 @@ class ReactiveSolidUpdates : public CoupledSolidUpdates< NullModel, PORO_TYPE, P void updateStateFromPressureAndReactions( localIndex const k, localIndex const q, real64 const & pressure, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & kineticReactionMolarIncrements ) const + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & kineticReactionMolarIncrements ) const { m_porosityUpdate.updateFromReactions( k, q, kineticReactionMolarIncrements ); real64 const porosity = m_porosityUpdate.getPorosity( k, q ); @@ -68,8 +68,8 @@ class ReactiveSolidUpdates : public CoupledSolidUpdates< NullModel, PORO_TYPE, P GEOS_HOST_DEVICE void updateSurfaceArea( localIndex const k, localIndex const q, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & initialSurfaceArea, - arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & surfaceArea ) const + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & initialSurfaceArea, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & surfaceArea ) const { real64 const porosity = m_porosityUpdate.getPorosity( k, q ); real64 const initialPorosity = m_porosityUpdate.getInitialPorosity( k, q ); diff --git a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp index cbc9c4016ff..43985b1a3cf 100644 --- a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp +++ b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp @@ -60,7 +60,7 @@ class ReactivePorosityUpdates : public PorosityBaseUpdates {} GEOS_HOST_DEVICE - void computePorosity( arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & kineticReactionMolarIncrements, + void computePorosity( arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & kineticReactionMolarIncrements, arraySlice1d< real64, reactivefluid::USD_SPECIES - 2 > const & volumeFractions, arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & volumeFractions_n, real64 & porosity, @@ -95,7 +95,7 @@ class ReactivePorosityUpdates : public PorosityBaseUpdates GEOS_HOST_DEVICE void updateFromReactions( localIndex const k, localIndex const q, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & kineticReactionMolarIncrements ) const + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & kineticReactionMolarIncrements ) const { computePorosity( kineticReactionMolarIncrements, m_volumeFractions[k][q], diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 734860723df..ef5ba360464 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -47,6 +47,40 @@ namespace geos using namespace dataRepository; using namespace constitutive; +template< typename POROUSWRAPPER_TYPE > +void updatePorosityAndPermeabilityFromPressureAndReactions( POROUSWRAPPER_TYPE porousWrapper, + ElementSubRegionBase & subRegion, + arrayView1d< real64 const > const & pressure, + arrayView2d< real64 const, compflow::USD_COMP > const & kineticReactionMolarIncrements ) +{ + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_DEVICE ( localIndex const k ) + { + for( localIndex q = 0; q < porousWrapper.numGauss(); ++q ) + { + porousWrapper.updateStateFromPressureAndReactions( k, q, + pressure[k], + kineticReactionMolarIncrements[k] ); + } + } ); +} + +template< typename POROUSWRAPPER_TYPE > +void updateSurfaceAreaFromReactions( POROUSWRAPPER_TYPE porousWrapper, + ElementSubRegionBase & subRegion, + arrayView2d< real64 const, compflow::USD_COMP > const & initialSurfaceArea, + arrayView2d< real64, compflow::USD_COMP > const & surfaceArea ) +{ + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_DEVICE ( localIndex const k ) + { + for( localIndex q = 0; q < porousWrapper.numGauss(); ++q ) + { + porousWrapper.updateSurfaceArea( k, q, + initialSurfaceArea[k], + surfaceArea[k] ); + } + } ); +} + SinglePhaseReactiveTransport::SinglePhaseReactiveTransport( const string & name, Group * const parent ): SinglePhaseBase( name, parent ), @@ -631,15 +665,7 @@ void SinglePhaseReactiveTransport::updatePorosityAndPermeability( CellElementSub constitutive::ConstitutivePassThru< ReactiveSolidBase >::execute( porousSolid, [=, &subRegion] ( auto & castedPorousSolid ) { typename TYPEOFREF( castedPorousSolid ) ::KernelWrapper porousWrapper = castedPorousSolid.createKernelUpdates(); - forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_DEVICE ( localIndex const k ) - { - for( localIndex q = 0; q < porousWrapper.numGauss(); ++q ) - { - porousWrapper.updateStateFromPressureAndReactions( k, q, - pressure[k], - kineticReactionMolarIncrements[k] ); - } - } ); + updatePorosityAndPermeabilityFromPressureAndReactions( porousWrapper, subRegion, pressure, kineticReactionMolarIncrements ); } ); } else @@ -696,15 +722,7 @@ void SinglePhaseReactiveTransport::updateSurfaceArea( ElementSubRegionBase & sub constitutive::ConstitutivePassThru< ReactiveSolidBase >::execute( porousSolid, [=, &subRegion] ( auto & castedPorousSolid ) { typename TYPEOFREF( castedPorousSolid ) ::KernelWrapper porousWrapper = castedPorousSolid.createKernelUpdates(); - forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_DEVICE ( localIndex const k ) - { - for( localIndex q = 0; q < porousWrapper.numGauss(); ++q ) - { - porousWrapper.updateSurfaceArea( k, q, - initialSurfaceArea[k], - surfaceArea[k] ); - } - } ); + updateSurfaceAreaFromReactions( porousWrapper, subRegion, initialSurfaceArea, surfaceArea ); } ); } else From 90d3e52e936ac64c066a7159319a4a1480f4435f Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Fri, 15 Aug 2025 17:00:27 -0700 Subject: [PATCH 44/66] addded both advective and diffusive cases --- .../MoMaSBenchmark/MoMaS_advective_base.xml | 78 ++++++++++++++++++ ...oMaS_main.xml => MoMaS_advective_main.xml} | 3 +- .../MoMaSBenchmark/MoMaS_base.xml | 77 +----------------- .../MoMaSBenchmark/MoMaS_diffusive_base.xml | 78 ++++++++++++++++++ .../MoMaSBenchmark/MoMaS_diffusive_main.xml | 79 +++++++++++++++++++ 5 files changed, 239 insertions(+), 76 deletions(-) create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_base.xml rename inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/{MoMaS_main.xml => MoMaS_advective_main.xml} (96%) create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_base.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_main.xml diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_base.xml new file mode 100644 index 00000000000..190e6e7af0b --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_base.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_main.xml similarity index 96% rename from inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_main.xml rename to inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_main.xml index fb27e810e36..9dd8e16c1d6 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_main.xml @@ -3,6 +3,7 @@ + @@ -15,7 +16,7 @@ xCoords="{-0.01, 0, 1, 1.1, 2.1, 2.11 }" yCoords="{ 0, 1 }" zCoords="{ 0, 1 }" - nx="{ 1, 100, 10, 100, 1 }" + nx="{ 1, 100, 40, 100, 1 }" ny="{ 1 }" nz="{ 1 }" cellBlockNames="{ cb-0_0_0, cb-1_0_0, cb-2_0_0, cb-3_0_0, cb-4_0_0 }"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml index 50a95ec3892..693cfa9915f 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml @@ -13,12 +13,12 @@ + directParallel="1"/> @@ -29,79 +29,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_main.xml new file mode 100644 index 00000000000..3290a6f764c --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_main.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 7f2acbf97f25f83e5f48448a6cd6b978ddcaed1f Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Tue, 26 Aug 2025 13:19:32 -0700 Subject: [PATCH 45/66] fixed logInfo --- .../fluidFlow/SinglePhaseReactiveTransport.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index ef5ba360464..72253bc949a 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -30,7 +30,6 @@ #include "constitutive/solid/CoupledSolidBase.hpp" #include "constitutive/solid/ReactiveSolid.hpp" #include "fieldSpecification/FieldSpecificationManager.hpp" -#include "fieldSpecification/LogLevelsInfo.hpp" #include "fieldSpecification/SourceFluxBoundaryCondition.hpp" #include "physicsSolvers/fluidFlow/SourceFluxStatistics.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp" @@ -106,6 +105,8 @@ SinglePhaseReactiveTransport::SinglePhaseReactiveTransport( const string & name, setApplyDefaultValue( { } ). setInputFlag( InputFlags::OPTIONAL ). setDescription( "Array to store the indices of immobile species. Default is {}, which indicates no immobile species." ); + + addLogLevel< logInfo::BoundaryConditions >(); } // TODO: we need to update the class of ReactiveSingleFluid to be consistent with the chemistry module!!! @@ -926,7 +927,7 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, if( m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) { globalIndex const numTargetElems = MpiWrapper::sum< globalIndex >( targetSet.size() ); - GEOS_LOG_LEVEL_RANK_0_ON_GROUP( logInfo::BoundaryCondition, + GEOS_LOG_LEVEL_RANK_0_ON_GROUP( logInfo::BoundaryConditions, GEOS_FMT( bcLogMessage, getName(), time_n+dt, fs.getCatalogName(), fs.getName(), setName, subRegion.getName(), fs.getScale(), numTargetElems ), @@ -939,9 +940,9 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, } if( !subRegion.hasWrapper( dofKey ) ) { - GEOS_LOG_LEVEL_BY_RANK_ON_GROUP( logInfo::SourceFluxFailure, - GEOS_FMT( "{}: trying to apply SourceFlux, but its targetSet named '{}' intersects with non-simulated region named '{}'.", - getDataContext(), setName, subRegion.getName() ), + GEOS_LOG_LEVEL_BY_RANK_ON_GROUP( logInfo::BoundaryConditions, + GEOS_FMT( "{}: trying to apply {}, but its targetSet named '{}' intersects with non-simulated region named '{}'.", + getDataContext(), SourceFluxBoundaryCondition::catalogName(), setName, subRegion.getName() ), fs ); return; } From 2f12d37783f0cd01cf81f087e3435bcd28e12b0d Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Wed, 27 Aug 2025 13:22:12 -0700 Subject: [PATCH 46/66] added initial primary species array and cleaned up xmls --- ...tionCarbonateSystemPorosityUpdate_main.xml | 2 +- ...ionCarbonateSystem_initialPrimaryConc.xml} | 84 +++++----- .../mixedReactionCarbonateSystem_main.xml | 2 +- .../MoMaSBenchmark/MoMaS_advective_main.xml | 2 +- .../MoMaSBenchmark/MoMaS_diffusive_main.xml | 4 +- .../MoMaSBenchmark/MoMaS_initialAggregate.xml | 4 +- .../MoMaSBenchmark/MoMaS_initialLogConc.xml | 97 ------------ .../MoMaS_initialPrimaryConc.xml | 143 ++++++++++++++++++ .../MoMaSBenchmark/MoMaS_logConc.xml | 8 +- .../MoMaSSmoke/MoMaS_base.xml | 23 --- .../MoMaSSmoke/MoMaS_initialAggregate.xml | 4 +- .../MoMaSSmoke/MoMaS_initialLogConc.xml | 52 ------- .../MoMaSSmoke/MoMaS_initialPrimaryConc.xml | 98 ++++++++++++ .../MoMaSSmoke/MoMaS_logConc.xml | 8 +- .../MoMaSSmoke/MoMaS_main.xml | 11 +- .../reactivefluid/ReactiveFluidFields.hpp | 6 +- .../ReactiveSinglePhaseFluid.cpp | 4 +- .../ReactiveSinglePhaseFluid.hpp | 22 ++- 18 files changed, 324 insertions(+), 250 deletions(-) rename inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/{mixedReactionCarbonateSystem_initialLogConc.xml => mixedReactionCarbonateSystem_initialPrimaryConc.xml} (57%) delete mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialLogConc.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialPrimaryConc.xml delete mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialLogConc.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialPrimaryConc.xml diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml index f72a7fa371a..26074ddb384 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystemPorosityUpdate_main.xml @@ -4,7 +4,7 @@ - + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialLogConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialPrimaryConc.xml similarity index 57% rename from inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialLogConc.xml rename to inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialPrimaryConc.xml index 88f98093984..9fe0e5abeae 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialLogConc.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_initialPrimaryConc.xml @@ -4,130 +4,130 @@ + scale="1.585e-7"/> + scale="8.293e-3"/> + scale="2.171e-3"/> + scale="1.666e-6"/> + scale="2.821e-5"/> + scale="1.605e-3"/> + scale="7.817e-4"/> + scale="1.585e-7"/> + scale="7.317e-2"/> + scale="1.517e-2"/> + scale="1.666e-6"/> + scale="2.821e-5"/> + scale="1.605e-3"/> + scale="7.817e-4"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml index afe71dad376..3d6a6de7754 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/1DCarbonateSystem/mixedReactionCarbonateSystem_main.xml @@ -4,7 +4,7 @@ - + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_main.xml index 9dd8e16c1d6..98909bcb8d8 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_main.xml @@ -6,7 +6,7 @@ - + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_main.xml index 3290a6f764c..1b809461a01 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_main.xml @@ -6,7 +6,7 @@ - + @@ -72,7 +72,7 @@ diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialAggregate.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialAggregate.xml index 208f64b9e11..96fd60bb97a 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialAggregate.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialAggregate.xml @@ -129,7 +129,7 @@ objectPath="ElementRegions/Source" fieldName="water_primarySpeciesAggregateConcentration" component="3" - scale="1e-5"/> + scale="1e-20"/> + scale="1e-20"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialLogConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialLogConc.xml deleted file mode 100644 index c5779e62959..00000000000 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialLogConc.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialPrimaryConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialPrimaryConc.xml new file mode 100644 index 00000000000..bdb82dbd19a --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialPrimaryConc.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_logConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_logConc.xml index adb33481542..b694ac4c669 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_logConc.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_logConc.xml @@ -17,7 +17,7 @@ objectPath="ElementRegions/Source" fieldName="logPrimarySpeciesConcentration" component="1" - scale="-1.4206052082"/> + scale="-1.4203896610"/> + scale="-1.4203896610"/> + scale="-116.6994524874"/> + scale="-54.1859471371"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml index 6c7f5ce9919..0fd8e12ae06 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml @@ -29,11 +29,6 @@ - - - - @@ -128,19 +117,7 @@ scale="1.0e6"/> - - - - diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialAggregate.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialAggregate.xml index dd2dc218830..67937e658db 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialAggregate.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialAggregate.xml @@ -83,7 +83,7 @@ objectPath="ElementRegions/Source" fieldName="water_primarySpeciesAggregateConcentration" component="3" - scale="1e-5"/> + scale="1e-20"/> + scale="1e-20"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialLogConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialLogConc.xml deleted file mode 100644 index d86540e727e..00000000000 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialLogConc.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialPrimaryConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialPrimaryConc.xml new file mode 100644 index 00000000000..d876342094d --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_initialPrimaryConc.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_logConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_logConc.xml index adb33481542..b694ac4c669 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_logConc.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_logConc.xml @@ -17,7 +17,7 @@ objectPath="ElementRegions/Source" fieldName="logPrimarySpeciesConcentration" component="1" - scale="-1.4206052082"/> + scale="-1.4203896610"/> + scale="-1.4203896610"/> + scale="-116.6994524874"/> + scale="-54.1859471371"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml index d0465f58805..2700613496e 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_main.xml @@ -5,7 +5,7 @@ - + @@ -35,15 +35,6 @@ cycleFrequency="1" target="/Outputs/vtkOutput"/> - - ; using array4dLayoutSpecies_dC = array4d< real64, constitutive::reactivefluid::LAYOUT_SPECIES_DC >; -DECLARE_FIELD( primarySpeciesConcentration, - "primarySpeciesConcentration", +DECLARE_FIELD( initialPrimarySpeciesConcentration, + "initialPrimarySpeciesConcentration", array3dLayoutSpecies, 1e-16, LEVEL_0, WRITE_AND_READ, - "primarySpeciesConcentration" ); + "initialPrimarySpeciesConcentration" ); DECLARE_FIELD( primarySpeciesAggregateConcentration, "primarySpeciesAggregateConcentration", diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index 664c0b99938..701b54e8a8d 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -42,7 +42,8 @@ ReactiveSinglePhaseFluid( string const & name, Group * const parent ): setInputFlag( InputFlags::REQUIRED ). setDescription( "Chemical System type. Available options are: " "``" + EnumStrings< ChemicalSystemType >::concat( "|" ) + "``" ); - + + this->registerField( fields::reactivefluid::initialPrimarySpeciesConcentration{}, &m_initialPrimarySpeciesConcentration ); this->registerField( fields::reactivefluid::secondarySpeciesConcentration{}, &m_secondarySpeciesConcentration ); this->registerField( fields::reactivefluid::primarySpeciesAggregateConcentration{}, &m_primarySpeciesAggregateConcentration ); this->registerField( fields::reactivefluid::primarySpeciesAggregateConcentration_n{}, &m_primarySpeciesAggregateConcentration_n ); @@ -118,6 +119,7 @@ void ReactiveSinglePhaseFluid< BASE >::resizeFields( localIndex const size, loca integer const numSecondarySpecies = this->numSecondarySpecies(); integer const numKineticReactions = this->numKineticReactions(); + m_initialPrimarySpeciesConcentration.resize( size, numPts, numPrimarySpecies ); m_secondarySpeciesConcentration.resize( size, numPts, numSecondarySpecies ); m_primarySpeciesAggregateConcentration.resize( size, numPts, numPrimarySpecies ); m_primarySpeciesAggregateConcentration_n.resize( size, numPts, numPrimarySpecies ); diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index 0b6d10be396..c0d01690ddb 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -123,6 +123,7 @@ class ReactiveSinglePhaseFluid : public BASE arrayView3d< real64, reactivefluid::USD_SPECIES > const & primarySpeciesMobileAggregateConcentration, arrayView4d< real64, reactivefluid::USD_SPECIES_DC > const & dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, arrayView4d< real64, reactivefluid::USD_SPECIES_DC > const & dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const & initialPrimarySpeciesConcentration, arrayView3d< real64, reactivefluid::USD_SPECIES > const & secondarySpeciesConcentration, arrayView3d< real64, reactivefluid::USD_SPECIES > const & kineticReactionRates, arrayView3d< real64, reactivefluid::USD_SPECIES > const & aggregateSpeciesRates, @@ -138,6 +139,7 @@ class ReactiveSinglePhaseFluid : public BASE m_primarySpeciesMobileAggregateConcentration( primarySpeciesMobileAggregateConcentration ), m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations( dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations ), m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations( dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations ), + m_initialPrimarySpeciesConcentration( initialPrimarySpeciesConcentration ), m_secondarySpeciesConcentration( secondarySpeciesConcentration ), m_kineticReactionRates( kineticReactionRates ), m_aggregateSpeciesRates( aggregateSpeciesRates ), @@ -163,9 +165,10 @@ class ReactiveSinglePhaseFluid : public BASE GEOS_HOST_DEVICE void enforceEquilibrium( real64 const pressure, real64 const temperature, - arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & primarySpeciesTotalConcentration, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & primarySpeciesConcentration, - arraySlice1d< real64 > const & secondarySpeciesConcentration ) const; + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & targetPrimarySpeciesAggregateConcentration, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & initialPrimarySpeciesConcentration, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, + arraySlice1d< real64 > const & logSecondarySpeciesConcentration ) const; GEOS_HOST_DEVICE void updateMixedReactionSystem( localIndex const k, @@ -205,6 +208,8 @@ class ReactiveSinglePhaseFluid : public BASE arrayView4d< real64, reactivefluid::USD_SPECIES_DC > m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations; + arrayView3d< real64 const, reactivefluid::USD_SPECIES > const m_initialPrimarySpeciesConcentration; + arrayView3d< real64, reactivefluid::USD_SPECIES > m_secondarySpeciesConcentration; arrayView3d< real64, reactivefluid::USD_SPECIES > m_kineticReactionRates; @@ -233,6 +238,7 @@ class ReactiveSinglePhaseFluid : public BASE m_primarySpeciesMobileAggregateConcentration, m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_initialPrimarySpeciesConcentration, m_secondarySpeciesConcentration, m_kineticReactionRates, m_aggregateSpeciesRates, @@ -247,6 +253,7 @@ class ReactiveSinglePhaseFluid : public BASE m_primarySpeciesMobileAggregateConcentration, m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_initialPrimarySpeciesConcentration, m_secondarySpeciesConcentration, m_kineticReactionRates, m_aggregateSpeciesRates, @@ -260,6 +267,7 @@ class ReactiveSinglePhaseFluid : public BASE m_primarySpeciesMobileAggregateConcentration, m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_initialPrimarySpeciesConcentration, m_secondarySpeciesConcentration, m_kineticReactionRates, m_aggregateSpeciesRates, @@ -273,6 +281,7 @@ class ReactiveSinglePhaseFluid : public BASE m_primarySpeciesMobileAggregateConcentration, m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_initialPrimarySpeciesConcentration, m_secondarySpeciesConcentration, m_kineticReactionRates, m_aggregateSpeciesRates, @@ -301,6 +310,8 @@ class ReactiveSinglePhaseFluid : public BASE integer m_numKineticReactions; + array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_initialPrimarySpeciesConcentration; + array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_secondarySpeciesConcentration; array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_primarySpeciesAggregateConcentration; @@ -341,7 +352,7 @@ updateEquilibriumReaction( localIndex const k, stackArray1d< real64, MAX_NUM_SPECIES > logSecondarySpeciesConcentration( numSecondarySpecies ); - enforceEquilibrium( pressure, temperature, m_primarySpeciesAggregateConcentration[k][0], logPrimarySpeciesConcentration, logSecondarySpeciesConcentration.toSlice() ); + enforceEquilibrium( pressure, temperature, m_primarySpeciesAggregateConcentration[k][0], m_initialPrimarySpeciesConcentration[k][0], logPrimarySpeciesConcentration, logSecondarySpeciesConcentration.toSlice() ); for( integer i=0; i < numSecondarySpecies; ++i ) { @@ -358,6 +369,7 @@ ReactiveSinglePhaseFluid< BASE >::ReactionKernelWrapper< REACTION_PARAMS_TYPE >: enforceEquilibrium( real64 const pressure, real64 const temperature, arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & targetPrimarySpeciesAggregateConcentration, + arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & initialPrimarySpeciesConcentration, arraySlice1d< real64, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, arraySlice1d< real64 > const & logSecondarySpeciesConcentration ) const { @@ -371,7 +383,7 @@ enforceEquilibrium( real64 const pressure, for( integer i=0; i < numPrimarySpecies; ++i ) { targetPrimarySpeciesAggregateConc[i] = targetPrimarySpeciesAggregateConcentration[i]; - logPrimarySpeciesConcentration0[i] = logPrimarySpeciesConcentration[i]; + logPrimarySpeciesConcentration0[i] = LvArray::math::log( initialPrimarySpeciesConcentration[i] ); } // 1. We enforce equilibrium From 50960268ea2690f8b3b776e305667c3a1681fede Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Wed, 3 Sep 2025 15:58:14 -0700 Subject: [PATCH 47/66] updated 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 6d0282aa944..f20e43a4b6f 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 6d0282aa944e8fb2efbe0abe8fd1acf5e2e645a1 +Subproject commit f20e43a4b6fcebd8e9996c46edcdde48fb31f806 From 616c3400cd7348331d3bc396d6381d0970703f14 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Fri, 12 Sep 2025 14:56:20 -0700 Subject: [PATCH 48/66] enable momas medium test case --- .../MoMaS_advective_base.xml | 102 +++++++++++ .../MoMaS_advective_main.xml | 92 ++++++++++ .../MoMaSBenchmarkMedium1D/MoMaS_base.xml | 161 ++++++++++++++++++ .../MoMaS_initialAggregate.xml | 143 ++++++++++++++++ .../MoMaS_initialPrimaryConc.xml | 143 ++++++++++++++++ .../MoMaSBenchmarkMedium1D/MoMaS_logConc.xml | 89 ++++++++++ .../MoMaSSmoke/MoMaS_base.xml | 2 +- src/coreComponents/constitutive/HPCReact | 2 +- .../ReactiveSinglePhaseFluid.cpp | 6 + .../ReactiveSinglePhaseFluid.hpp | 51 ++++-- .../reactive/AccumulationKernels.hpp | 4 +- 11 files changed, 775 insertions(+), 20 deletions(-) create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_advective_base.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_advective_main.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_base.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_initialAggregate.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_initialPrimaryConc.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_logConc.xml diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_advective_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_advective_base.xml new file mode 100644 index 00000000000..23a175c8d66 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_advective_base.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_advective_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_advective_main.xml new file mode 100644 index 00000000000..52023bbc79b --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_advective_main.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_base.xml new file mode 100644 index 00000000000..010801d8648 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_base.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_initialAggregate.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_initialAggregate.xml new file mode 100644 index 00000000000..2fb76a9a089 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_initialAggregate.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_initialPrimaryConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_initialPrimaryConc.xml new file mode 100644 index 00000000000..992465e12c3 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_initialPrimaryConc.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_logConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_logConc.xml new file mode 100644 index 00000000000..1b39e7f1cfa --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_logConc.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml index 0fd8e12ae06..d68d6f952a9 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSSmoke/MoMaS_base.xml @@ -48,7 +48,7 @@ referencePressure="0.0" compressibility="0.0" viscosibility="0.0" - chemicalSystemType="momas"/> + chemicalSystemType="momasEasy"/> ::postInputInitialization() m_numKineticReactions = 0; break; + case ChemicalSystemType::momasMedium: + m_numPrimarySpecies = 5; + m_numSecondarySpecies = 9; + m_numKineticReactions = 1; + break; + default: m_numPrimarySpecies = 5; m_numSecondarySpecies = 7; diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index c0d01690ddb..530e10d202a 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -51,7 +51,8 @@ enum class ChemicalSystemType : integer carbonate, carbonateAllEquilibrium, ultramafic, - momas + momasEasy, + momasMedium }; template< typename BASE > @@ -225,11 +226,12 @@ class ReactiveSinglePhaseFluid : public BASE typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::geochemistry::ultramaficSystemType >, typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::geochemistry::carbonateSystemType >, typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::geochemistry::carbonateSystemAllEquilibriumType >, - typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::MomMasBenchmark::simpleSystemType > > + typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::MoMasBenchmark::mediumCaseType >, + typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::MoMasBenchmark::easyCaseType > > createReactionKernelWrapper() const { using namespace hpcReact::geochemistry; - using namespace hpcReact::MomMasBenchmark; + using namespace hpcReact::MoMasBenchmark; using namespace hpcReact::bulkGeneric; switch( m_chemicalSystemType ) { @@ -276,20 +278,34 @@ class ReactiveSinglePhaseFluid : public BASE m_numSecondarySpecies, m_numKineticReactions, carbonateSystemAllEquilibrium ); + case ChemicalSystemType::momasMedium: + return ReactionKernelWrapper< mediumCaseType >( m_primarySpeciesAggregateConcentration, + m_primarySpeciesMobileAggregateConcentration, + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_initialPrimarySpeciesConcentration, + m_secondarySpeciesConcentration, + m_kineticReactionRates, + m_aggregateSpeciesRates, + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, + m_numPrimarySpecies, + m_numSecondarySpecies, + m_numKineticReactions, + mediumCaseParams ); default: - return ReactionKernelWrapper< simpleSystemType >( m_primarySpeciesAggregateConcentration, - m_primarySpeciesMobileAggregateConcentration, - m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, - m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, - m_initialPrimarySpeciesConcentration, - m_secondarySpeciesConcentration, - m_kineticReactionRates, - m_aggregateSpeciesRates, - m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, - m_numPrimarySpecies, - m_numSecondarySpecies, - m_numKineticReactions, - simpleSystemParams ); + return ReactionKernelWrapper< easyCaseType >( m_primarySpeciesAggregateConcentration, + m_primarySpeciesMobileAggregateConcentration, + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_initialPrimarySpeciesConcentration, + m_secondarySpeciesConcentration, + m_kineticReactionRates, + m_aggregateSpeciesRates, + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, + m_numPrimarySpecies, + m_numSecondarySpecies, + m_numKineticReactions, + easyCaseParams ); } } @@ -474,7 +490,8 @@ ENUM_STRINGS( ChemicalSystemType, "carbonate", "carbonateAllEquilibrium", "ultramafic", - "momas" ); + "momasEasy", + "momasMedium" ); } // namespace reactivefluid diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp index 240cd272b2b..891229efa74 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp @@ -184,13 +184,15 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU stack.localResidual[is+numEqn-numSpecies] += m_primarySpeciesAggregateConcentration[ei][0][is] * stack.poreVolume; // Reaction term - stack.localResidual[is+numEqn-numSpecies] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * m_primarySpeciesAggregateKineticRate[ei][0][is]; + // stack.localResidual[is+numEqn-numSpecies] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * m_primarySpeciesAggregateKineticRate[ei][0][is]; + stack.localResidual[is+numEqn-numSpecies] -= m_dt * stack.poreVolume * m_primarySpeciesAggregateKineticRate[ei][0][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][0][is] /* + stack.poreVolume * m_dTotalPrimarySpeciesConcentration_dPres[ei][is] */; // // Derivative of reaction term wrt pressure + stack.localJacobian[is+numEqn-numSpecies][0] -= m_dt * stack.dPoreVolume_dPres * m_primarySpeciesAggregateKineticRate[ei][0][is]; // stack.localJacobian[is+numEqn-numSpecies][0] -= m_dt * ( m_volume[ei] + m_deltaVolume[ei] ) * // m_dPrimarySpeciesTotalKineticRate_dPres[is]; From e920071cd94659ceb36cc09f948bcf49a52197b0 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Fri, 12 Sep 2025 15:12:50 -0700 Subject: [PATCH 49/66] renamed the momas input file deck folder and added the 2D problem --- .../MoMaS_advective_base.xml | 44 ++++-- .../MoMaS_advective_main.xml | 33 +++- .../MoMaS_base.xml | 70 +++++---- .../MoMaS_diffusive_base.xml | 44 ++++-- .../MoMaS_diffusive_main.xml | 45 +++++- .../MoMaS_initialAggregate.xml | 8 +- .../MoMaS_initialPrimaryConc.xml | 4 +- .../MoMaS_logConc.xml | 0 .../MoMaS_2DAdvective_base.xml | 103 +++++++++++++ .../MoMaS_2DAdvective_main.xml | 55 +++++++ .../MoMaSBenchmarkEasy2D/MoMaS_base.xml | 81 ++++++++++ .../MoMaS_initialAggregate.xml | 143 ++++++++++++++++++ .../MoMaS_initialPrimaryConc.xml | 143 ++++++++++++++++++ .../MoMaSBenchmarkEasy2D/MoMaS_logConc.xml | 46 ++++++ 14 files changed, 755 insertions(+), 64 deletions(-) rename inputFiles/singlePhaseFlow/reactiveTransport/{MoMaSBenchmark => MoMaSBenchmarkEasy1D}/MoMaS_advective_base.xml (57%) rename inputFiles/singlePhaseFlow/reactiveTransport/{MoMaSBenchmark => MoMaSBenchmarkEasy1D}/MoMaS_advective_main.xml (69%) rename inputFiles/singlePhaseFlow/reactiveTransport/{MoMaSBenchmark => MoMaSBenchmarkEasy1D}/MoMaS_base.xml (70%) rename inputFiles/singlePhaseFlow/reactiveTransport/{MoMaSBenchmark => MoMaSBenchmarkEasy1D}/MoMaS_diffusive_base.xml (58%) rename inputFiles/singlePhaseFlow/reactiveTransport/{MoMaSBenchmark => MoMaSBenchmarkEasy1D}/MoMaS_diffusive_main.xml (63%) rename inputFiles/singlePhaseFlow/reactiveTransport/{MoMaSBenchmark => MoMaSBenchmarkEasy1D}/MoMaS_initialAggregate.xml (97%) rename inputFiles/singlePhaseFlow/reactiveTransport/{MoMaSBenchmark => MoMaSBenchmarkEasy1D}/MoMaS_initialPrimaryConc.xml (98%) rename inputFiles/singlePhaseFlow/reactiveTransport/{MoMaSBenchmark => MoMaSBenchmarkEasy1D}/MoMaS_logConc.xml (100%) create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_2DAdvective_base.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_2DAdvective_main.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_base.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_initialAggregate.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_initialPrimaryConc.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_logConc.xml diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_base.xml similarity index 57% rename from inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_base.xml rename to inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_base.xml index 190e6e7af0b..220cbce513c 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_base.xml @@ -1,21 +1,45 @@ + + + + + + + + materialList="{ water, rock_a, diffusionA }"/> + cellBlocks="{ cb-1_0_0, cb-2_0_0, cb-4_0_0, cb-5_0_0 }" + materialList="{ water, rock_a, diffusionA }"/> + cellBlocks="{ cb-3_0_0 }" + materialList="{ water, rock_b, diffusionB }"/> @@ -26,7 +50,7 @@ referencePressure="0.0" compressibility="0.0" viscosibility="0.0" - chemicalSystemType="momas"/> + chemicalSystemType="momasEasy"/> + diffusivityComponents="{ 22e-5, 22e-5, 22e-5 }"/> + diffusivityComponents="{ 6.6e-4, 6.6e-4, 6.6e-4 }"/> \ No newline at end of file diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_main.xml similarity index 69% rename from inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_main.xml rename to inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_main.xml index 98909bcb8d8..7834b0dc408 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_advective_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_main.xml @@ -13,29 +13,33 @@ + cellBlockNames="{ cb-0_0_0, cb-1_0_0, cb-2_0_0, cb-3_0_0, cb-4_0_0, cb-5_0_0 }"/> + xMax="{ 3.101, 1.01, 1.01 }"/> + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_base.xml similarity index 70% rename from inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml rename to inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_base.xml index 693cfa9915f..f811d7496cc 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_base.xml @@ -1,27 +1,6 @@ - - - - - - - + scale="1.0"/> + + + + + scale="1e6"/> + + - + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_base.xml similarity index 58% rename from inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_base.xml rename to inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_base.xml index fff84cf4525..ea9e95609e1 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_base.xml @@ -1,21 +1,45 @@ + + + + + + + + materialList="{ water, rock_a, diffusionA }"/> + cellBlocks="{ cb-1_0_0, cb-2_0_0, cb-4_0_0, cb-5_0_0 }" + materialList="{ water, rock_a, diffusionA }"/> + cellBlocks="{ cb-3_0_0 }" + materialList="{ water, rock_b, diffusionB }"/> @@ -26,7 +50,7 @@ referencePressure="0.0" compressibility="0.0" viscosibility="0.0" - chemicalSystemType="momas"/> + chemicalSystemType="momasEasy"/> + diffusivityComponents="{ 22e-2, 22e-2, 22e-2 }"/> + diffusivityComponents="{ 0.66, 0.66, 0.66 }"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_main.xml similarity index 63% rename from inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_main.xml rename to inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_main.xml index 1b809461a01..c2474fe80c6 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_diffusive_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_main.xml @@ -13,29 +13,33 @@ + cellBlockNames="{ cb-0_0_0, cb-1_0_0, cb-2_0_0, cb-3_0_0, cb-4_0_0, cb-5_0_0 }"/> + xMax="{ 3.101, 1.01, 1.01 }"/> + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialAggregate.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_initialAggregate.xml similarity index 97% rename from inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialAggregate.xml rename to inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_initialAggregate.xml index 96fd60bb97a..d17545e2d17 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmark/MoMaS_initialAggregate.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_initialAggregate.xml @@ -10,7 +10,7 @@ objectPath="ElementRegions/MediumA" fieldName="water_primarySpeciesAggregateConcentration" component="0" - scale="1e-3"/> + scale="1e-8"/> + scale="1e-8"/> + scale="1e-8"/> + scale="1e-8"/> + scale="1e-8"/> + scale="1e-8"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_2DAdvective_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_2DAdvective_main.xml new file mode 100644 index 00000000000..756a23901ab --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_2DAdvective_main.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_base.xml new file mode 100644 index 00000000000..7c4059813cc --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_base.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_initialAggregate.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_initialAggregate.xml new file mode 100644 index 00000000000..d17545e2d17 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_initialAggregate.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_initialPrimaryConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_initialPrimaryConc.xml new file mode 100644 index 00000000000..0c996c4f429 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_initialPrimaryConc.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_logConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_logConc.xml new file mode 100644 index 00000000000..b694ac4c669 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy2D/MoMaS_logConc.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + From cbe97f9b637d603b676abb8e3096a30bc1554100 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Sun, 28 Sep 2025 14:32:51 -0700 Subject: [PATCH 50/66] enabled face dirichlet and updated xmls --- .../MoMaS_advective_main.xml | 4 +- .../MoMaSBenchmarkEasy1D/MoMaS_base.xml | 20 +- .../MoMaS_diffusive_main.xml | 2 +- .../MoMaS_advective_main.xml | 10 +- .../MoMaSBenchmarkMedium1D/MoMaS_base.xml | 4 +- .../physicsSolvers/fluidFlow/CMakeLists.txt | 2 + .../SinglePhaseReactiveTransport.cpp | 165 ++++++- .../SinglePhaseReactiveTransport.hpp | 22 +- .../DirichletFluxComputeKernel.hpp | 11 +- .../ThermalDirichletFluxComputeKernel.hpp | 7 +- .../reactive/DirichletFluxComputeKernel.hpp | 361 +++++++++++++++ .../ThermalDirichletFluxComputeKernel.hpp | 410 ++++++++++++++++++ .../reactive/ThermalFluxComputeKernel.hpp | 1 + 13 files changed, 983 insertions(+), 36 deletions(-) create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/DirichletFluxComputeKernel.hpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_main.xml index 7834b0dc408..4bf15542a1d 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_main.xml @@ -13,10 +13,10 @@ diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_base.xml index f811d7496cc..6b77cb0a620 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_base.xml @@ -25,14 +25,6 @@ fieldName="rockPorosityA_referencePorosity" scale="0.25"/> - - - - diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_main.xml index c2474fe80c6..81596a7122f 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_main.xml @@ -13,7 +13,7 @@ + maxTime="5200"> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_base.xml index 010801d8648..3ec05662134 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_base.xml @@ -65,8 +65,8 @@ diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt index d90c70996a9..d6f47d94d3f 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt +++ b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt @@ -66,12 +66,14 @@ set( fluidFlowSolvers_headers kernels/singlePhase/proppant/ProppantBaseKernels.hpp kernels/singlePhase/proppant/ProppantFluxKernels.hpp kernels/singlePhase/reactive/AccumulationKernels.hpp + kernels/singlePhase/reactive/DirichletFluxComputeKernel.hpp 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/ThermalDirichletFluxComputeKernel.hpp kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp kernels/compositional/AccumulationKernel.hpp kernels/compositional/AquiferBCKernel.hpp diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 72253bc949a..c2ba3b9e8b8 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -109,7 +109,6 @@ SinglePhaseReactiveTransport::SinglePhaseReactiveTransport( const string & name, addLogLevel< logInfo::BoundaryConditions >(); } -// 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; @@ -857,12 +856,14 @@ void SinglePhaseReactiveTransport::applyBoundaryConditions( real64 const time_n, { GEOS_MARK_FUNCTION; - // apply pressure boundary conditions. + // apply Dirichlet boundary conditions. applyDirichletBC( time_n, dt, domain, dofManager, localMatrix.toViewConstSizes(), localRhs.toView() ); // apply flux boundary conditions applySourceFluxBC( time_n, dt, domain, dofManager, localMatrix.toViewConstSizes(), localRhs.toView() ); + // apply face Dirichlet boundary conditions. + applyFaceDirichletBC( time_n, dt, dofManager, domain, localMatrix, localRhs ); } void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, @@ -1547,6 +1548,166 @@ void SinglePhaseReactiveTransport::saveConvergedState( ElementSubRegionBase & su primarySpeciesAggregateMole_n.setValues< parallelDevicePolicy<> >( primarySpeciesAggregateMole ); } +namespace +{ +char const faceBcLogMessage[] = + "SinglePhaseReactiveTransport {}: at time {}s, " + "the <{}> boundary condition '{}' is applied to the face set '{}' in '{}'. " + "\nThe scale of this boundary condition is {} and multiplies the value of the provided function (if any). " + "\nThe total number of target faces (including ghost faces) is {}." + "\nNote that if this number is equal to zero, the boundary condition will not be applied on this face set."; +} + +void SinglePhaseReactiveTransport::applyFaceDirichletBC( real64 const time_n, + real64 const dt, + DofManager const & dofManager, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) +{ + GEOS_MARK_FUNCTION; + + array1d< integer > mobilePrimarySpeciesFlags; + mobilePrimarySpeciesFlags.resize( m_numPrimarySpecies ); + + for( integer i=0; i 0 ) + { + for( integer i = 0; i < m_immobilePrimarySpeciesIndices.size(); ++i ) + { + localIndex const immobileSpeciesIndex = m_immobilePrimarySpeciesIndices[i]; + mobilePrimarySpeciesFlags[immobileSpeciesIndex] = 0; + } + } + + FieldSpecificationManager & fsManager = FieldSpecificationManager::getInstance(); + + NumericalMethodsManager const & numericalMethodManager = domain.getNumericalMethodManager(); + FiniteVolumeManager const & fvManager = numericalMethodManager.getFiniteVolumeManager(); + FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName ); + + string const & dofKey = dofManager.getKey( SinglePhaseBase::viewKeyStruct::elemDofFieldString() ); + + this->forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &, + MeshLevel & mesh, + string_array const & ) + { + FaceManager & faceManager = mesh.getFaceManager(); + ElementRegionManager & elemManager = mesh.getElemManager(); + + if( m_isThermal ) + { + // Take BCs defined for "pressure" field and apply values to "facePressure" + applyFieldValue< FaceManager >( time_n, dt, mesh, faceBcLogMessage, + fields::flow::pressure::key(), fields::flow::facePressure::key() ); + + // Take BCs defined for "temperature" field and apply values to "faceTemperature" + applyFieldValue< FaceManager >( time_n, dt, mesh, faceBcLogMessage, + fields::flow::temperature::key(), fields::flow::faceTemperature::key() ); + + // Then launch the face Dirichlet kernel + fsManager.apply< FaceManager >( time_n + dt, + mesh, + fields::flow::pressure::key(), // we have required that pressure is always present + [&] ( FieldSpecificationBase const &, + string const & setName, + SortedArrayView< localIndex const > const &, + FaceManager &, + string const & ) + { + BoundaryStencil const & stencil = fluxApprox.getStencil< BoundaryStencil >( mesh, setName ); + if( stencil.size() == 0 ) + { + return; + } + + // TODO: same issue as in the single-phase case + // currently we just use model from the first cell in this stencil + // since it's not clear how to create fluid kernel wrappers for arbitrary models. + // Can we just use cell properties for an approximate flux computation? + // Then we can forget about capturing the fluid model. + localIndex const er = stencil.getElementRegionIndices()( 0, 0 ); + localIndex const esr = stencil.getElementSubRegionIndices()( 0, 0 ); + ElementSubRegionBase & subRegion = elemManager.getRegion( er ).getSubRegion( esr ); + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & reactiveFluid = subRegion.getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( fluidName ); + + BoundaryStencilWrapper const stencilWrapper = stencil.createKernelWrapper(); + + thermalSinglePhaseReactiveFVMKernels:: + DirichletFluxComputeKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, + mobilePrimarySpeciesFlags, + dofManager.rankOffset(), + dofKey, + this->getName(), + faceManager, + elemManager, + stencilWrapper, + reactiveFluid, + dt, + localMatrix, + localRhs ); + } ); + } + else + { + // Take BCs defined for "pressure" field and apply values to "facePressure" + applyFieldValue< FaceManager >( time_n, dt, mesh, faceBcLogMessage, + fields::flow::pressure::key(), fields::flow::facePressure::key() ); + + // Then launch the face Dirichlet kernel + fsManager.apply< FaceManager >( time_n + dt, + mesh, + fields::flow::pressure::key(), // we have required that pressure is always present + [&] ( FieldSpecificationBase const &, + string const & setName, + SortedArrayView< localIndex const > const &, + FaceManager &, + string const & ) + { + BoundaryStencil const & stencil = fluxApprox.getStencil< BoundaryStencil >( mesh, setName ); + if( stencil.size() == 0 ) + { + return; + } + + // TODO: same issue as in the single-phase case + // currently we just use model from the first cell in this stencil + // since it's not clear how to create fluid kernel wrappers for arbitrary models. + // Can we just use cell properties for an approximate flux computation? + // Then we can forget about capturing the fluid model. + localIndex const er = stencil.getElementRegionIndices()( 0, 0 ); + localIndex const esr = stencil.getElementSubRegionIndices()( 0, 0 ); + ElementSubRegionBase & subRegion = elemManager.getRegion( er ).getSubRegion( esr ); + string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); + reactivefluid::ReactiveCompressibleSinglePhaseFluid & reactiveFluid = subRegion.getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( fluidName ); + + BoundaryStencilWrapper const stencilWrapper = stencil.createKernelWrapper(); + + singlePhaseReactiveFVMKernels:: + DirichletFluxComputeKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, + mobilePrimarySpeciesFlags, + dofManager.rankOffset(), + dofKey, + this->getName(), + faceManager, + elemManager, + stencilWrapper, + reactiveFluid, + dt, + localMatrix, + localRhs ); + } ); + } + } ); +} + void SinglePhaseReactiveTransport::assembleEDFMFluxTerms( real64 const GEOS_UNUSED_PARAM( time_n ), real64 const GEOS_UNUSED_PARAM( dt ), DomainPartition const & GEOS_UNUSED_PARAM( domain ), diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index f9e5cc3a476..5acc21b56c5 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -25,11 +25,13 @@ #include "physicsSolvers/fluidFlow/SinglePhaseFVM.hpp" #include "physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/DirichletFluxComputeKernel.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 "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp" #include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp" @@ -308,6 +310,24 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase /// array to store the indices of immobile primary species array1d< integer > m_immobilePrimarySpeciesIndices; +private: + + /** + * @brief Function to perform the application of Dirichlet BCs on faces + * @param time_n current time + * @param dt time step + * @param faceSet degree-of-freedom manager associated with the linear system + * @param domain the domain + * @param matrix the system matrix + * @param rhs the system right-hand side vector + */ + void applyFaceDirichletBC( real64 const time_n, + real64 const dt, + DofManager const & faceSet, + DomainPartition & domain, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ); + }; template< typename OBJECT_TYPE > @@ -348,4 +368,4 @@ void SinglePhaseReactiveTransport::applyFieldValue( real64 const & time_n, } /* namespace geos */ -#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVETRANSPORT_HPP_ +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVETRANSPORT_HPP_ \ No newline at end of file diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/DirichletFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/DirichletFluxComputeKernel.hpp index 15c9ecc7a48..d05ea6e706f 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/DirichletFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/DirichletFluxComputeKernel.hpp @@ -27,6 +27,7 @@ #include "finiteVolume/BoundaryStencil.hpp" #include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" #include "physicsSolvers/fluidFlow/StencilAccessors.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/FluxComputeKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/MobilityKernel.hpp" #include "codingUtilities/Utilities.hpp" @@ -44,8 +45,8 @@ namespace singlePhaseFVMKernels * @brief Define the interface for the assembly kernel in charge of Dirichlet face flux terms */ template< integer NUM_EQN, integer NUM_DOF, typename FLUIDWRAPPER > -class DirichletFluxComputeKernel : public FluxComputeKernel< NUM_EQN, NUM_DOF, - BoundaryStencilWrapper > +class DirichletFluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_EQN, NUM_DOF, + BoundaryStencilWrapper > { public: using Deriv = constitutive::singlefluid::DerivativeOffset; @@ -223,10 +224,14 @@ class DirichletFluxComputeKernel : public FluxComputeKernel< NUM_EQN, NUM_DOF, real64 const mobility_up = mobility[k_up]; real64 const dMobility_dP_up = dMobility_dP[k_up]; + // Upwind density + real64 const dens_up = ( potDif >= 0 ) ? m_dens[er][esr][ei][0] : faceDens; + real64 const dDens_dP_up = ( potDif >= 0 ) ? m_dDens[er][esr][ei][0][Deriv::dP] : 0.0; + // call the lambda in the phase loop to allow the reuse of the fluxes and their derivatives // possible use: assemble the derivatives wrt temperature, and the flux term of the energy equation for this phase - compFluxKernelOp( er, esr, ei, kf, f, dF_dP, mobility_up, dMobility_dP_up ); + compFluxKernelOp( er, esr, ei, kf, f, dF_dP, mobility_up, dMobility_dP_up, dens_up, dDens_dP_up ); // *** end of upwinding diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ThermalDirichletFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ThermalDirichletFluxComputeKernel.hpp index bcd1b1bc880..e6db619c950 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ThermalDirichletFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ThermalDirichletFluxComputeKernel.hpp @@ -200,9 +200,12 @@ class DirichletFluxComputeKernel : public singlePhaseFVMKernels::DirichletFluxCo real64 const & f, real64 const & dF_dP, real64 const & mobility_up, - real64 const & dMobility_dP_up ) + real64 const & dMobility_dP_up, + real64 const & dens_up, + real64 const & dDens_dP_up ) { - + GEOS_UNUSED_VAR( dens_up, dDens_dP_up ); + // Compute the derivatives of the density wrt temperature real64 const dDens_dT = 0.5 * m_dDens[er][esr][ei][0][DerivOffset::dT]; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/DirichletFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/DirichletFluxComputeKernel.hpp new file mode 100644 index 00000000000..cdf9e9c2f5e --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/DirichletFluxComputeKernel.hpp @@ -0,0 +1,361 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 DirichletFluxComputeKernel.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_DIRICHLETFLUXCOMPUTEKERNEL_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_DIRICHLETFLUXCOMPUTEKERNEL_HPP + +#include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveFluidSelector.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/DirichletFluxComputeKernel.hpp" + +namespace geos +{ + +namespace singlePhaseReactiveFVMKernels +{ + +/******************************** DirichletFluxComputeKernel ********************************/ + +/** + * @class DirichletFluxComputeKernel + * @tparam NUM_SPECIES number of fluid primary species + * @tparam NUM_EQN number of equations + * @tparam NUM_DOF number of degrees of freedom + * @tparam FLUIDWRAPPER the type of the fluid wrapper + * @tparam BASE_FLUID_TYPE the type of the base model for the reactive fluid model + * @brief Define the interface for the assembly kernel in charge of Dirichlet face flux terms + */ +template< integer NUM_SPECIES, integer NUM_EQN, integer NUM_DOF, typename FLUIDWRAPPER, typename BASE_FLUID_TYPE > +class DirichletFluxComputeKernel : public singlePhaseFVMKernels::DirichletFluxComputeKernel< NUM_EQN, NUM_DOF, + FLUIDWRAPPER > +{ +public: + /// Compile time value for the number of primary species + static constexpr integer numSpecies = NUM_SPECIES; + + /** + * @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_dens; + using AbstractBase::m_dDens; + + using Base = singlePhaseFVMKernels::DirichletFluxComputeKernel< NUM_EQN, NUM_DOF, + FLUIDWRAPPER >; + using Base::numDof; + using Base::numEqn; + using Base::m_stencilWrapper; + using Base::m_seri; + using Base::m_sesri; + using Base::m_sei; + + using Base::m_facePres; + using Base::m_fluidWrapper; + + using ReactiveSinglePhaseFlowAccessors = + StencilAccessors< fields::flow::logPrimarySpeciesConcentration, + fields::flow::dMobility_dLogPrimaryConc >; + + using ReactiveSinglePhaseFluidAccessors = + StencilMaterialAccessors< constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE >, + fields::reactivefluid::primarySpeciesMobileAggregateConcentration, + fields::reactivefluid::dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations >; + + /** + * @brief Constructor for the kernel interface + * @param[in] rankOffset the offset of my MPI rank + * @param[in] faceManager the face manager + * @param[in] stencilWrapper reference to the stencil wrapper + * @param[in] fluidWrapper reference to the fluid 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 + */ + DirichletFluxComputeKernel( globalIndex const rankOffset, + FaceManager const & faceManager, + BoundaryStencilWrapper const & stencilWrapper, + FLUIDWRAPPER const & fluidWrapper, + DofNumberAccessor const & dofNumberAccessor, + SinglePhaseFlowAccessors const & singlePhaseFlowAccessors, + ReactiveSinglePhaseFlowAccessors const & reactiveSinglePhaseFlowAccessors, + SinglePhaseFluidAccessors const & singlePhaseFluidAccessors, + ReactiveSinglePhaseFluidAccessors const & reactiveSinglePhaseFluidAccessors, + PermeabilityAccessors const & permeabilityAccessors, + arrayView1d< integer const > const & mobilePrimarySpeciesFlags, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + : Base( rankOffset, + faceManager, + stencilWrapper, + fluidWrapper, + dofNumberAccessor, + singlePhaseFlowAccessors, + singlePhaseFluidAccessors, + permeabilityAccessors, + dt, + localMatrix, + localRhs ), + m_dMob_dLogPrimaryConc( reactiveSinglePhaseFlowAccessors.get( fields::flow::dMobility_dLogPrimaryConc {} ) ), + m_primarySpeciesMobileAggregateConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::primarySpeciesMobileAggregateConcentration {} ) ), + m_dPrimarySpeciesMobileAggregateConc_dLogPrimaryConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations {} ) ), + m_mobilePrimarySpeciesFlags( mobilePrimarySpeciesFlags ) + {} + + /** + * @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::transmissibility; + using Base::StackVariables::dofColIndices; + using Base::StackVariables::localFlux; + using Base::StackVariables::localFluxJacobian; + + }; + + /** + * @brief Compute the local Dirichlet face flux contributions to the residual and Jacobian + * @param[in] iconn the connection index + * @param[inout] stack the stack variables + * @param[in] compFluxKernelOp the function used to customize the computation of the component fluxes + */ + template< typename FUNC = NoOpFunc > + GEOS_HOST_DEVICE + void computeFlux( localIndex const iconn, + StackVariables & stack, + FUNC && compFluxKernelOp = NoOpFunc{} ) const + { + Base::computeFlux( iconn, stack, [&] ( localIndex const seri, + localIndex const sesri, + localIndex const sei, + localIndex const kf, + real64 const & fluxVal, + real64 const & dFlux_dP, + real64 const & mobility_up, + real64 const & dMobility_dP_up, + real64 const & dens_up, + real64 const & dDens_dP_up ) + { + GEOS_UNUSED_VAR( kf ); + + real64 speciesFlux[numSpecies]{}; + real64 dSpeciesFlux_dP[numSpecies]{}; + real64 dSpeciesFlux_dLogConc[numSpecies][numSpecies]{}; + + for( integer is = 0; is < numSpecies; ++is ) + { + real64 const aggregateConc_i = m_primarySpeciesMobileAggregateConc[seri][sesri][sei][0][is]; + speciesFlux[is] = aggregateConc_i / dens_up * fluxVal * mobility_up; + + dSpeciesFlux_dP[is] = aggregateConc_i / dens_up * dFlux_dP * mobility_up + + aggregateConc_i / dens_up * fluxVal * dMobility_dP_up + - aggregateConc_i * fluxVal * mobility_up * dDens_dP_up / (dens_up * dens_up); + + for( integer js = 0; js < numSpecies; ++js ) + { + real64 const dAggregateConc_i_dLogConc_j = m_dPrimarySpeciesMobileAggregateConc_dLogPrimaryConc[seri][sesri][sei][0][is][js]; + dSpeciesFlux_dLogConc[is][js] += dAggregateConc_i_dLogConc_j / dens_up * fluxVal * mobility_up; + } + } + + /// populate local flux vector and derivatives + for( integer is = 0; is < numSpecies; ++is ) + { + stack.localFlux[numEqn - numSpecies + is] = m_dt * speciesFlux[is] * m_mobilePrimarySpeciesFlags[is]; + stack.localFluxJacobian[numEqn - numSpecies + is][0] = m_dt * dSpeciesFlux_dP[is] * m_mobilePrimarySpeciesFlags[is]; + + for( integer js = 0; js < numSpecies; ++js ) + { + stack.localFluxJacobian[numEqn - numSpecies + is][numDof - numSpecies + js] += m_dt * dSpeciesFlux_dLogConc[is][js] * m_mobilePrimarySpeciesFlags[is]; + } + } + + compFluxKernelOp( seri, sesri, sei, kf, fluxVal, dFlux_dP, mobility_up, dMobility_dP_up ); + } ); + } + + /** + * @brief Performs the complete phase for the kernel. + * @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, + FUNC && assemblyKernelOp = NoOpFunc{} ) const + { + Base::complete( iconn, stack, [&] ( localIndex const localRow ) + { + for( integer is = 0; is < numSpecies; ++is ) + { + RAJA::atomicAdd( parallelDeviceAtomic{}, &AbstractBase::m_localRhs[localRow + numEqn - numSpecies + is], + stack.localFlux[numEqn - numSpecies + is] ); + + AbstractBase::m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic > + ( localRow + numEqn - numSpecies + is, + stack.dofColIndices, + stack.localFluxJacobian[numEqn - numSpecies + is], + numDof ); + } + + assemblyKernelOp( localRow ); + } ); + } + +protected: + + /// Views on derivatives of fluid mobilities + ElementViewConst< arrayView2d< real64 const, compflow::USD_FLUID_DC > > const m_dMob_dLogPrimaryConc; + + /// Views on primary species aggregate concentration + ElementViewConst< arrayView3d< real64 const, constitutive::reactivefluid::USD_SPECIES > > const m_primarySpeciesMobileAggregateConc; + + /// Views on the derivative of primary species mobile aggregate concentration wrt log of primary concentration + ElementViewConst< arrayView4d< real64 const, constitutive::reactivefluid::USD_SPECIES_DC > > const m_dPrimarySpeciesMobileAggregateConc_dLogPrimaryConc; + + /// Array of flags to indicate mobile primary species + arrayView1d< integer const > const m_mobilePrimarySpeciesFlags; + +}; + + +/** + * @class DirichletFluxComputeKernelFactory + */ +class DirichletFluxComputeKernelFactory +{ +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] mobilePrimarySpeciesFlags the array of flags to indicate mobile 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] faceManager reference to the face manager + * @param[in] elemManager reference to the element region manager + * @param[in] stencilWrapper reference to the boundary stencil wrapper + * @param[in] reactiveFluid the single phase reactive fluid constitutive model + * @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 > + static void + createAndLaunch( integer const numSpecies, + arrayView1d< integer const > const mobilePrimarySpeciesFlags, + globalIndex const rankOffset, + string const & dofKey, + string const & solverName, + FaceManager const & faceManager, + ElementRegionManager const & elemManager, + BoundaryStencilWrapper const & stencilWrapper, + constitutive::reactivefluid::ReactiveCompressibleSinglePhaseFluid & reactiveFluid, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + constitutiveUpdatePassThru( reactiveFluid, [&]( auto & fluid ) + { + using FluidType = TYPEOFREF( fluid ); + typename FluidType::KernelWrapper fluidWrapper = fluid.createKernelWrapper(); + + singlePhaseReactiveBaseKernels::internal::kernelLaunchSelectorCompSwitch( numSpecies, [&]( auto NS ) + { + integer constexpr NUM_SPECIES = NS(); + integer constexpr NUM_DOF = 1+NS(); + integer constexpr NUM_EQN = 1+NS(); + + using kernelType = DirichletFluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, typename FluidType::KernelWrapper, + constitutive::CompressibleSinglePhaseFluid >; + + ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > > dofNumberAccessor = + elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); + + dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); + + typename kernelType::SinglePhaseFlowAccessors singlePhaseFlowAccessors( elemManager, solverName ); + typename kernelType::ReactiveSinglePhaseFlowAccessors reactiveFlowAccessors( elemManager, solverName ); + typename kernelType::SinglePhaseFluidAccessors singlePhaseFluidAccessors( elemManager, solverName ); + typename kernelType::ReactiveSinglePhaseFluidAccessors reactiveFluidAccessors( elemManager, solverName ); + typename kernelType::PermeabilityAccessors permeabilityAccessors( elemManager, solverName ); + + kernelType kernel( rankOffset, + faceManager, + stencilWrapper, + fluidWrapper, + dofNumberAccessor, + singlePhaseFlowAccessors, + reactiveFlowAccessors, + singlePhaseFluidAccessors, + reactiveFluidAccessors, + permeabilityAccessors, + mobilePrimarySpeciesFlags, + dt, + localMatrix, + localRhs ); + + kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); + } ); + } ); + } + +}; + +} // namespace singlePhaseReactiveFVMKernels + +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_DIRICHLETFLUXCOMPUTEKERNEL_HPP diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp new file mode 100644 index 00000000000..4f3a75f74fa --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp @@ -0,0 +1,410 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ThermalDirichletFluxComputeKernel.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_THERMALDIRICHLETFLUXCOMPUTEKERNEL_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_THERMALDIRICHLETFLUXCOMPUTEKERNEL_HPP + +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/DirichletFluxComputeKernel.hpp" + +#include "constitutive/thermalConductivity/SinglePhaseThermalConductivityBase.hpp" +#include "constitutive/thermalConductivity/ThermalConductivityFields.hpp" + +namespace geos +{ + +namespace thermalSinglePhaseReactiveFVMKernels +{ + +/******************************** DirichletFluxComputeKernel ********************************/ + +/** + * @class DirichletFluxComputeKernel + * @tparam NUM_SPECIES number of fluid primary species + * @tparam NUM_EQN number of equations + * @tparam NUM_DOF number of degrees of freedom + * @tparam FLUIDWRAPPER the type of the fluid wrapper + * @tparam BASE_FLUID_TYPE the type of the base model for the reactive fluid model + * @brief Define the interface for the assembly kernel in charge of Dirichlet face flux terms + */ +template< integer NUM_SPECIES, integer NUM_EQN, integer NUM_DOF, typename FLUIDWRAPPER, typename BASE_FLUID_TYPE > +class DirichletFluxComputeKernel : public singlePhaseReactiveFVMKernels::DirichletFluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, FLUIDWRAPPER, BASE_FLUID_TYPE > +{ +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 + */ + + using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; + template< typename VIEWTYPE > + using ElementViewConst = ElementRegionManager::ElementViewConst< VIEWTYPE >; + + using AbstractBase = singlePhaseFVMKernels::FluxComputeKernelBase; + using DofNumberAccessor = AbstractBase::DofNumberAccessor; + using PermeabilityAccessors = AbstractBase::PermeabilityAccessors; + using SinglePhaseFlowAccessors = AbstractBase::SinglePhaseFlowAccessors; + using SinglePhaseFluidAccessors = AbstractBase::SinglePhaseFluidAccessors; + + using AbstractBase::m_dt; + using AbstractBase::m_rankOffset; + using AbstractBase::m_dofNumber; + using AbstractBase::m_ghostRank; + using AbstractBase::m_gravCoef; + using AbstractBase::m_mob; + using AbstractBase::m_pres; + using AbstractBase::m_permeability; + using AbstractBase::m_dPerm_dPres; + using AbstractBase::m_dDens; + using AbstractBase::m_dMob; + + using Base = singlePhaseReactiveFVMKernels::DirichletFluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, FLUIDWRAPPER, BASE_FLUID_TYPE >; + using Base::numSpecies; + using Base::numDof; + using Base::numEqn; + using Base::m_stencilWrapper; + using Base::m_seri; + using Base::m_sesri; + using Base::m_sei; + using Base::m_facePres; + using Base::m_faceGravCoef; + + using ReactiveSinglePhaseFlowAccessors = typename Base::ReactiveSinglePhaseFlowAccessors; + using ReactiveSinglePhaseFluidAccessors = typename Base::ReactiveSinglePhaseFluidAccessors; + + using ThermalSinglePhaseFlowAccessors = + StencilAccessors< fields::flow::temperature >; + + using ThermalReactiveSinglePhaseFluidAccessors = + StencilMaterialAccessors< constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE >, + 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 the MPI rank + * @param[in] faceManager the face manager + * @param[in] stencilWrapper reference to the stencil wrapper + * @param[in] fluidWrapper reference to the fluid wrapper + * @param[in] dofNumberAccessor the degree of freedom number accessor + * @param[in] singlePhaseFlowAccessors the single phase flow accessor + * @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 the single phase fluid accessor + * @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 the permeability accessor + * @param[in] thermalConductivityAccessors the thermal conductivity accessor + * @param[in] mobilePrimarySpeciesFlags the array of flags to indicate mobile primary species + * @param[in] dt the time step size + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + */ + DirichletFluxComputeKernel( globalIndex const rankOffset, + FaceManager const & faceManager, + BoundaryStencilWrapper const & stencilWrapper, + FLUIDWRAPPER const & fluidWrapper, + DofNumberAccessor const & dofNumberAccessor, + SinglePhaseFlowAccessors const & singlePhaseFlowAccessors, + ReactiveSinglePhaseFlowAccessors const & reactiveSinglePhaseFlowAccessors, + ThermalSinglePhaseFlowAccessors const & thermalSinglePhaseFlowAccessors, + SinglePhaseFluidAccessors const & singlePhaseFluidAccessors, + ReactiveSinglePhaseFluidAccessors const & reactiveSinglePhaseFluidAccessors, + ThermalReactiveSinglePhaseFluidAccessors const & thermalReactiveSinglePhaseFluidAccessors, + PermeabilityAccessors const & permeabilityAccessors, + ThermalConductivityAccessors const & thermalConductivityAccessors, + arrayView1d< integer const > const & mobilePrimarySpeciesFlags, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + + : Base( rankOffset, + faceManager, + stencilWrapper, + fluidWrapper, + dofNumberAccessor, + singlePhaseFlowAccessors, + reactiveSinglePhaseFlowAccessors, + singlePhaseFluidAccessors, + reactiveSinglePhaseFluidAccessors, + permeabilityAccessors, + mobilePrimarySpeciesFlags, + dt, + localMatrix, + localRhs ), + m_temp( thermalSinglePhaseFlowAccessors.get( fields::flow::temperature {} ) ), + m_faceTemp( faceManager.getField< fields::flow::faceTemperature >() ), + m_enthalpy( thermalReactiveSinglePhaseFluidAccessors.get( fields::singlefluid::enthalpy {} ) ), + m_dEnthalpy( thermalReactiveSinglePhaseFluidAccessors.get( fields::singlefluid::dEnthalpy {} ) ), + m_thermalConductivity( thermalConductivityAccessors.get( fields::thermalconductivity::effectiveConductivity {} ) ), + m_dThermalCond_dT( thermalConductivityAccessors.get( fields::thermalconductivity::dEffectiveConductivity_dT {} ) ) + {} + + + /** + * @struct StackVariables + * @brief Kernel variables (dof numbers, jacobian and residual) located on the stack + */ + struct StackVariables : 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::localFlux; + using Base::StackVariables::localFluxJacobian; + using Base::StackVariables::dofColIndices; + using Base::StackVariables::transmissibility; + + /// Energy fluxes and derivatives wrt pressure and temperature + real64 energyFlux = 0.0; + real64 dEnergyFlux_dP = 0.0; + real64 dEnergyFlux_dT = 0.0; + }; + + /** + * @brief Compute the local Dirichlet face flux contributions to the residual and Jacobian + * @tparam FUNC the type of the function that can be used to customize the computation of the phase fluxes + * @param[in] iconn the connection index + * @param[inout] stack the stack variables + * @param[in] compFluxKernelOp the function used to customize the computation of the component fluxes + */ + GEOS_HOST_DEVICE + void computeFlux( localIndex const iconn, + StackVariables & stack ) const + { + Base::computeFlux( iconn, stack, [&] ( localIndex const er, + localIndex const esr, + localIndex const ei, + localIndex const kf, + real64 const & f, + real64 const & dF_dP, + real64 const & mobility_up, + real64 const & dMobility_dP_up ) + { + // Compute the derivatives of the density wrt temperature + + real64 const dDens_dT = 0.5 * m_dDens[er][esr][ei][0][DerivOffset::dT]; + // Compute the derivatives of the phase potential difference wrt temperature + + real64 const dF_dT = -stack.transmissibility * dDens_dT * ( m_gravCoef[er][esr][ei] - m_faceGravCoef[kf] ); + + // Compute the (upwinded) energy flux + + real64 const flux = mobility_up * f; + real64 const enthalpy = m_enthalpy[er][esr][ei][0]; + stack.energyFlux += flux * enthalpy; + + // Compute the derivatives of the (upwinded) energy flux wrt pressure and temperature + + if( f >= 0 ) // the element is upstream + { + real64 const dFlux_dP = mobility_up * dF_dP + dMobility_dP_up * f; + real64 const dFlux_dT = mobility_up * dF_dT + m_dMob[er][esr][ei][DerivOffset::dT] * f; + + stack.dEnergyFlux_dP += dFlux_dP * enthalpy + flux * m_dEnthalpy[er][esr][ei][0][DerivOffset::dP]; + stack.dEnergyFlux_dT += dFlux_dT * enthalpy + flux * m_dEnthalpy[er][esr][ei][0][DerivOffset::dT]; + } + else + { + real64 const dFlux_dP = mobility_up * dF_dP; + real64 const dFlux_dT = mobility_up * dF_dT; + + stack.dEnergyFlux_dP += dFlux_dP * enthalpy; + stack.dEnergyFlux_dT += dFlux_dT * enthalpy; + } + + // Contribution of energy conduction through the solid phase + real64 thermalTrans = 0.0; + real64 dThermalTrans_dThermalCond[3]{}; + m_stencilWrapper.computeWeights( iconn, + m_thermalConductivity, + thermalTrans, + dThermalTrans_dThermalCond ); + + real64 const dThermalTrans_dT = LvArray::tensorOps::AiBi< 3 >( dThermalTrans_dThermalCond, m_dThermalCond_dT[er][esr][ei][0] ); + + real64 const deltaT = m_temp[er][esr][ei] - m_faceTemp[kf]; + stack.energyFlux += thermalTrans * deltaT; + stack.dEnergyFlux_dT += thermalTrans + dThermalTrans_dT * deltaT; + + // Add energyFlux and its derivatives to localFlux and localFluxJacobian + integer const localRowIndexEnergy = numEqn - numSpecies - 1; + stack.localFlux[localRowIndexEnergy] = m_dt * stack.energyFlux; + + stack.localFluxJacobian[localRowIndexEnergy][0] = m_dt * stack.dEnergyFlux_dP; + stack.localFluxJacobian[localRowIndexEnergy][numDof-numSpecies-1] = m_dt * stack.dEnergyFlux_dT; + } ); + + } + + /** + * @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 + { + Base::complete( iconn, stack, [&] ( localIndex const localRow ) + { + RAJA::atomicAdd( parallelDeviceAtomic{}, &AbstractBase::m_localRhs[localRow + numEqn - numSpecies - 1], + stack.localFlux[numEqn - numSpecies - 1] ); + + AbstractBase::m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic > + ( localRow + numEqn - numSpecies - 1, + stack.dofColIndices, + stack.localFluxJacobian[numEqn - numSpecies - 1], + numDof ); + } ); + } + +protected: + + /// Views on temperature + ElementViewConst< arrayView1d< real64 const > > const m_temp; + + /// Views on face temperature + arrayView1d< real64 const > const m_faceTemp; + + /// 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; + + /// 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 DirichletFluxComputeKernelFactory + */ +class DirichletFluxComputeKernelFactory +{ +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] mobilePrimarySpeciesFlags the array of flags to indicate mobile 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] faceManager reference to the face manager + * @param[in] elemManager reference to the element region manager + * @param[in] stencilWrapper reference to the boundary stencil wrapper + * @param[in] reactiveFluid the single phase reactive fluid constitutive model + * @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 > + static void + createAndLaunch( integer const numSpecies, + arrayView1d< integer const > const mobilePrimarySpeciesFlags, + globalIndex const rankOffset, + string const & dofKey, + string const & solverName, + FaceManager const & faceManager, + ElementRegionManager const & elemManager, + BoundaryStencilWrapper const & stencilWrapper, + constitutive::reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & reactiveFluid, + real64 const & dt, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) + { + constitutiveUpdatePassThru( reactiveFluid, [&]( auto & fluid ) + { + using FluidType = TYPEOFREF( fluid ); + typename FluidType::KernelWrapper fluidWrapper = fluid.createKernelWrapper(); + + singlePhaseReactiveBaseKernels::internal::kernelLaunchSelectorCompSwitch( numSpecies, [&]( auto NS ) + { + integer constexpr NUM_SPECIES = NS(); + integer constexpr NUM_DOF = 2+NS(); + integer constexpr NUM_EQN = 2+NS(); + + using kernelType = DirichletFluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, typename FluidType::KernelWrapper, constitutive::ThermalCompressibleSinglePhaseFluid >; + + ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > > dofNumberAccessor = + elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey ); + + dofNumberAccessor.setName( solverName + "/accessors/" + dofKey ); + + typename kernelType::SinglePhaseFlowAccessors singlePhaseFlowAccessors( elemManager, solverName ); + typename kernelType::ReactiveSinglePhaseFlowAccessors reactiveFlowAccessors( elemManager, solverName ); + typename kernelType::ThermalSinglePhaseFlowAccessors thermalSinglePhaseFlowAccessors( elemManager, solverName ); + typename kernelType::SinglePhaseFluidAccessors singlePhaseFluidAccessors( elemManager, solverName ); + typename kernelType::ReactiveSinglePhaseFluidAccessors reactiveFluidAccessors( elemManager, solverName ); + typename kernelType::ThermalReactiveSinglePhaseFluidAccessors thermalFluidAccessors( elemManager, solverName ); + typename kernelType::PermeabilityAccessors permeabilityAccessors( elemManager, solverName ); + typename kernelType::ThermalConductivityAccessors thermalConductivityAccessors( elemManager, solverName ); + + kernelType kernel( rankOffset, + faceManager, + stencilWrapper, + fluidWrapper, + dofNumberAccessor, + singlePhaseFlowAccessors, + reactiveFlowAccessors, + thermalSinglePhaseFlowAccessors, + singlePhaseFluidAccessors, + reactiveFluidAccessors, + thermalFluidAccessors, + permeabilityAccessors, + thermalConductivityAccessors, + mobilePrimarySpeciesFlags, + dt, + localMatrix, + localRhs ); + + kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); + } ); + } ); + } + +}; + +} // namespace thermalSinglePhaseReactiveFVMKernels + +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_THERMALDIRICHLETFLUXCOMPUTEKERNEL_HPP diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp index 41ac478a001..c9295829042 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp @@ -38,6 +38,7 @@ namespace thermalSinglePhaseReactiveFVMKernels * @tparam NUM_EQN number of equations * @tparam NUM_DOF number of degrees of freedom * @tparam STENCILWRAPPER the type of the stencil wrapper + * @tparam BASE_FLUID_TYPE the type of the base model for the reactive fluid model * @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, typename BASE_FLUID_TYPE > From 73a1d79483845c54d3cbed837d642ba1d77efa2b Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Sun, 28 Sep 2025 14:33:31 -0700 Subject: [PATCH 51/66] corrections in momas medium in 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 3c384017ef1..2aeda9cd1c5 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 3c384017ef1f5e4bb2d2b5f10be53feb168736a8 +Subproject commit 2aeda9cd1c59e548a9ef8b3c804cfcee2ab75b32 From 872efc303a6ec3ca8d57b201a885a7f9a721da90 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Wed, 1 Oct 2025 14:16:52 -0700 Subject: [PATCH 52/66] link to 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 2aeda9cd1c5..7192d4717be 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 2aeda9cd1c59e548a9ef8b3c804cfcee2ab75b32 +Subproject commit 7192d4717be45d72beabeb7c972e7dcee190f352 From 31caa2a62e070062eb774f4c2a939891d5347496 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Wed, 22 Oct 2025 15:16:12 -0700 Subject: [PATCH 53/66] clean up for momas inputs and changed back for kinetic reaction term --- .../MoMaS_advective_main.xml | 25 ++++++--------- .../MoMaSBenchmarkEasy1D/MoMaS_base.xml | 18 +++-------- .../MoMaS_diffusive_base.xml | 6 ++-- .../MoMaS_diffusive_main.xml | 31 ++++--------------- .../MoMaS_advective_base.xml | 12 +++---- .../MoMaS_advective_main.xml | 17 +++++----- .../MoMaSBenchmarkMedium1D/MoMaS_base.xml | 20 +++--------- .../MoMaS_initialPrimaryConc.xml | 8 ++--- .../reactive/AccumulationKernels.hpp | 4 +-- 9 files changed, 47 insertions(+), 94 deletions(-) diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_main.xml index 4bf15542a1d..f44b3fde1d0 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_advective_main.xml @@ -30,16 +30,12 @@ + maxTime="5000"> - - + target="/Tasks/logPrimarySpeciesSinkCollection"/> + + target="/Outputs/logPrimarySpeciesSinkHistoryOutput"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_base.xml index 6b77cb0a620..aa3cf8c3932 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_base.xml @@ -72,11 +72,6 @@ - - @@ -104,11 +99,6 @@ - - + name="logPrimarySpeciesSinkHistoryOutput" + sources="{ /Tasks/logPrimarySpeciesSinkCollection }" + filename="logPrimarySpeciesSinkHistory"/> + directParallel="0"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_main.xml index 81596a7122f..09cdc2ef3f3 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkEasy1D/MoMaS_diffusive_main.xml @@ -36,10 +36,6 @@ cycleFrequency="100" target="/Outputs/vtkOutput"/> - - + target="/Tasks/logPrimarySpeciesSinkCollection"/> + + target="/Outputs/logPrimarySpeciesSinkHistoryOutput"/> - - - + logLevel="1"> + directParallel="0"/> diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_advective_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_advective_main.xml index 365bed3768a..ab2396f9633 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_advective_main.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_advective_main.xml @@ -36,10 +36,6 @@ cycleFrequency="2000" target="/Outputs/vtkOutput"/> - + target="/Tasks/logPrimarySpeciesSinkCollection"/> + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_base.xml index 3ec05662134..f1ed51c7534 100644 --- a/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_base.xml +++ b/inputFiles/singlePhaseFlow/reactiveTransport/MoMaSBenchmarkMedium1D/MoMaS_base.xml @@ -15,7 +15,7 @@ setNames="{ all }" objectPath="ElementRegions/Source" fieldName="rockPorosityA_referencePorosity" - scale="1.0"/> + scale="0.25"/> - - @@ -122,11 +117,6 @@ - - + name="logPrimarySpeciesSinkHistoryOutput" + sources="{ /Tasks/logPrimarySpeciesSinkCollection }" + filename="logPrimarySpeciesSinkHistory"/> + scale="2.0"/> + scale="10.0"/> + scale="1.0"/> + scale="1.0"/> Date: Wed, 22 Oct 2025 15:35:02 -0700 Subject: [PATCH 54/66] added generic chain reaction all kinetic case --- .../ChainSerial_allKinetic_base.xml | 74 ++++++++++++++++++ .../ChainSerial_allKinetic_main.xml | 52 +++++++++++++ .../ChainGenericSerial1D/ChainSerial_base.xml | 77 +++++++++++++++++++ .../ChainSerial_initialAggregate.xml | 61 +++++++++++++++ .../ChainSerial_logConc.xml | 31 ++++++++ src/coreComponents/constitutive/HPCReact | 2 +- .../reactivefluid/ReactiveFluidFields.hpp | 2 +- .../ReactiveSinglePhaseFluid.cpp | 6 ++ .../ReactiveSinglePhaseFluid.hpp | 39 ++++++++-- 9 files changed, 336 insertions(+), 8 deletions(-) create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_allKinetic_base.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_allKinetic_main.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_base.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_initialAggregate.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_logConc.xml diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_allKinetic_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_allKinetic_base.xml new file mode 100644 index 00000000000..27df60a6124 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_allKinetic_base.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_allKinetic_main.xml b/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_allKinetic_main.xml new file mode 100644 index 00000000000..d2d3be7c2b1 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_allKinetic_main.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_base.xml new file mode 100644 index 00000000000..4bc502df425 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_base.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_initialAggregate.xml b/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_initialAggregate.xml new file mode 100644 index 00000000000..a72597cb050 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_initialAggregate.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_logConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_logConc.xml new file mode 100644 index 00000000000..0cb9d89de44 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/ChainGenericSerial1D/ChainSerial_logConc.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/src/coreComponents/constitutive/HPCReact b/src/coreComponents/constitutive/HPCReact index 7192d4717be..d8dd4b7de58 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 7192d4717be45d72beabeb7c972e7dcee190f352 +Subproject commit d8dd4b7de58cdf9f37f63042fab18ea4777991fb diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp index 9b51a655fba..54e1c9a1fc2 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveFluidFields.hpp @@ -87,7 +87,7 @@ DECLARE_FIELD( secondarySpeciesConcentration, "secondarySpeciesConcentration", array3dLayoutSpecies, 1e-16, - LEVEL_0, + NOPLOT, WRITE_AND_READ, "secondarySpeciesConcentration" ); diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index 317177fead1..fce4370b1c2 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -96,6 +96,12 @@ void ReactiveSinglePhaseFluid< BASE >::postInputInitialization() m_numKineticReactions = 0; break; + case ChemicalSystemType::chainSerialAllKinetic: + m_numPrimarySpecies = 3; + m_numSecondarySpecies = 0; + m_numKineticReactions = 3; + break; + case ChemicalSystemType::momasMedium: m_numPrimarySpecies = 5; m_numSecondarySpecies = 9; diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index 530e10d202a..e121c3528fd 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -29,6 +29,7 @@ #include "constitutive/HPCReact/src/reactions/geochemistry/GeochemicalSystems.hpp" #include "constitutive/HPCReact/src/reactions/exampleSystems/BulkGeneric.hpp" +#include "constitutive/HPCReact/src/reactions/exampleSystems/ChainGeneric.hpp" #include "constitutive/HPCReact/src/reactions/exampleSystems/MoMasBenchmark.hpp" #include "constitutive/HPCReact/src/reactions/reactionsSystems/EquilibriumReactions.hpp" #include "constitutive/HPCReact/src/reactions/reactionsSystems/MixedEquilibriumKineticReactions.hpp" @@ -52,7 +53,8 @@ enum class ChemicalSystemType : integer carbonateAllEquilibrium, ultramafic, momasEasy, - momasMedium + momasMedium, + chainSerialAllKinetic }; template< typename BASE > @@ -226,6 +228,7 @@ class ReactiveSinglePhaseFluid : public BASE typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::geochemistry::ultramaficSystemType >, typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::geochemistry::carbonateSystemType >, typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::geochemistry::carbonateSystemAllEquilibriumType >, + typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::ChainGeneric::serialAllKineticType >, typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::MoMasBenchmark::mediumCaseType >, typename ReactiveSinglePhaseFluid< BASE >::template ReactionKernelWrapper< hpcReact::MoMasBenchmark::easyCaseType > > createReactionKernelWrapper() const @@ -233,6 +236,7 @@ class ReactiveSinglePhaseFluid : public BASE using namespace hpcReact::geochemistry; using namespace hpcReact::MoMasBenchmark; using namespace hpcReact::bulkGeneric; + using namespace hpcReact::ChainGeneric; switch( m_chemicalSystemType ) { case ChemicalSystemType::ultramafic: @@ -278,6 +282,20 @@ class ReactiveSinglePhaseFluid : public BASE m_numSecondarySpecies, m_numKineticReactions, carbonateSystemAllEquilibrium ); + case ChemicalSystemType::chainSerialAllKinetic: + return ReactionKernelWrapper< serialAllKineticType >( m_primarySpeciesAggregateConcentration, + m_primarySpeciesMobileAggregateConcentration, + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations, + m_initialPrimarySpeciesConcentration, + m_secondarySpeciesConcentration, + m_kineticReactionRates, + m_aggregateSpeciesRates, + m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations, + m_numPrimarySpecies, + m_numSecondarySpecies, + m_numKineticReactions, + serialAllKineticParams ); case ChemicalSystemType::momasMedium: return ReactionKernelWrapper< mediumCaseType >( m_primarySpeciesAggregateConcentration, m_primarySpeciesMobileAggregateConcentration, @@ -366,13 +384,21 @@ updateEquilibriumReaction( localIndex const k, { integer const numSecondarySpecies = m_numSecondarySpecies; - stackArray1d< real64, MAX_NUM_SPECIES > logSecondarySpeciesConcentration( numSecondarySpecies ); + if( numSecondarySpecies > 0 ) + { + stackArray1d< real64, MAX_NUM_SPECIES > logSecondarySpeciesConcentration( numSecondarySpecies ); - enforceEquilibrium( pressure, temperature, m_primarySpeciesAggregateConcentration[k][0], m_initialPrimarySpeciesConcentration[k][0], logPrimarySpeciesConcentration, logSecondarySpeciesConcentration.toSlice() ); + enforceEquilibrium( pressure, temperature, m_primarySpeciesAggregateConcentration[k][0], m_initialPrimarySpeciesConcentration[k][0], logPrimarySpeciesConcentration, + logSecondarySpeciesConcentration.toSlice() ); - for( integer i=0; i < numSecondarySpecies; ++i ) + for( integer i=0; i < numSecondarySpecies; ++i ) + { + m_secondarySpeciesConcentration[k][0][i] = LvArray::math::exp( logSecondarySpeciesConcentration[i] ); + } + } + else { - m_secondarySpeciesConcentration[k][0][i] = LvArray::math::exp( logSecondarySpeciesConcentration[i] ); + GEOS_UNUSED_VAR( k, pressure, temperature, logPrimarySpeciesConcentration ); } } @@ -491,7 +517,8 @@ ENUM_STRINGS( ChemicalSystemType, "carbonateAllEquilibrium", "ultramafic", "momasEasy", - "momasMedium" ); + "momasMedium", + "chainSerialAllKinetic" ); } // namespace reactivefluid From 280902b3aa1445348bc5f4913789461818b7d3f7 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Wed, 22 Oct 2025 15:36:07 -0700 Subject: [PATCH 55/66] revised unit test --- .../testSinglePhaseReactiveTransport.cpp | 189 ++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/src/coreComponents/integrationTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp b/src/coreComponents/integrationTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp index d4fe3e9570b..313972c4ffb 100644 --- a/src/coreComponents/integrationTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/integrationTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp @@ -192,7 +192,196 @@ char const * xmlInputCarbonate = fieldName="water_primarySpeciesAggregateConcentration" component="6" scale="7.817e-4"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Date: Wed, 22 Oct 2025 15:36:18 -0700 Subject: [PATCH 56/66] uncrustify --- .../constitutive/ConstitutivePassThru.hpp | 4 +- .../ReactiveSinglePhaseFluid.cpp | 36 ++--- .../ReactiveSinglePhaseFluid.hpp | 26 ++-- .../constitutive/solid/ReactiveSolid.hpp | 10 +- .../solid/porosity/ReactivePorosity.cpp | 16 +- .../solid/porosity/ReactivePorosity.hpp | 24 +-- .../testSinglePhaseReactiveTransport.cpp | 2 +- .../testSinglePhaseReactiveTransportUtils.hpp | 10 +- .../SinglePhaseReactiveTransport.cpp | 144 +++++++++--------- .../SinglePhaseReactiveTransport.hpp | 6 +- .../SinglePhaseReactiveTransportFields.hpp | 6 +- .../DirichletFluxComputeKernel.hpp | 2 +- .../ThermalDirichletFluxComputeKernel.hpp | 2 +- .../reactive/AccumulationKernels.hpp | 18 ++- .../reactive/DirichletFluxComputeKernel.hpp | 39 ++--- .../reactive/FluxComputeKernel.hpp | 5 +- .../ThermalDirichletFluxComputeKernel.hpp | 4 +- .../reactive/ThermalFluxComputeKernel.hpp | 2 +- 18 files changed, 185 insertions(+), 171 deletions(-) diff --git a/src/coreComponents/constitutive/ConstitutivePassThru.hpp b/src/coreComponents/constitutive/ConstitutivePassThru.hpp index 6511b4a810c..d5dc88018ab 100644 --- a/src/coreComponents/constitutive/ConstitutivePassThru.hpp +++ b/src/coreComponents/constitutive/ConstitutivePassThru.hpp @@ -470,7 +470,7 @@ struct ConstitutivePassThru< CoupledSolidBase > ReactiveSolid< ReactivePorosity, ConstantPermeability >, ReactiveSolid< ReactivePorosity, CarmanKozenyPermeability >, ReactiveSolid< ReactivePorosity, PressurePermeability > >::execute( constitutiveRelation, - std::forward< LAMBDA >( lambda ) ); + std::forward< LAMBDA >( lambda ) ); } template< typename LAMBDA > @@ -511,7 +511,7 @@ struct ConstitutivePassThru< CoupledSolidBase > ReactiveSolid< ReactivePorosity, ConstantPermeability >, ReactiveSolid< ReactivePorosity, CarmanKozenyPermeability >, ReactiveSolid< ReactivePorosity, PressurePermeability > >::execute( constitutiveRelation, - std::forward< LAMBDA >( lambda ) ); + std::forward< LAMBDA >( lambda ) ); } }; diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index fce4370b1c2..69b7b750934 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -42,14 +42,16 @@ ReactiveSinglePhaseFluid( string const & name, Group * const parent ): setInputFlag( InputFlags::REQUIRED ). setDescription( "Chemical System type. Available options are: " "``" + EnumStrings< ChemicalSystemType >::concat( "|" ) + "``" ); - + this->template registerField< fields::reactivefluid::initialPrimarySpeciesConcentration >( &m_initialPrimarySpeciesConcentration ); this->template registerField< fields::reactivefluid::secondarySpeciesConcentration >( &m_secondarySpeciesConcentration ); this->template registerField< fields::reactivefluid::primarySpeciesAggregateConcentration >( &m_primarySpeciesAggregateConcentration ); this->template registerField< fields::reactivefluid::primarySpeciesAggregateConcentration_n >( &m_primarySpeciesAggregateConcentration_n ); this->template registerField< fields::reactivefluid::primarySpeciesMobileAggregateConcentration >( &m_primarySpeciesMobileAggregateConcentration ); - this->template registerField< fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations >( &m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations ); - this->template registerField< fields::reactivefluid::dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations >( &m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations ); + this->template registerField< fields::reactivefluid::dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations >( + &m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations ); + this->template registerField< fields::reactivefluid::dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations >( + &m_dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations ); this->template registerField< fields::reactivefluid::kineticReactionRates >( &m_kineticReactionRates ); this->template registerField< fields::reactivefluid::aggregateSpeciesRates >( &m_aggregateSpeciesRates ); this->template registerField< fields::reactivefluid::dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations >( &m_dAggregateSpeciesRates_dLogPrimarySpeciesConcentrations ); @@ -63,10 +65,10 @@ deliverClone( string const & name, Group * const parent ) const ReactiveSinglePhaseFluid & newConstitutiveRelation = dynamicCast< ReactiveSinglePhaseFluid & >( *clone ); - newConstitutiveRelation.m_chemicalSystemType = m_chemicalSystemType; - newConstitutiveRelation.m_numPrimarySpecies = m_numPrimarySpecies; - newConstitutiveRelation.m_numSecondarySpecies = m_numSecondarySpecies; - newConstitutiveRelation.m_numKineticReactions = m_numKineticReactions; + newConstitutiveRelation.m_chemicalSystemType = m_chemicalSystemType; + newConstitutiveRelation.m_numPrimarySpecies = m_numPrimarySpecies; + newConstitutiveRelation.m_numSecondarySpecies = m_numSecondarySpecies; + newConstitutiveRelation.m_numKineticReactions = m_numKineticReactions; return clone; } @@ -79,20 +81,20 @@ void ReactiveSinglePhaseFluid< BASE >::postInputInitialization() switch( m_chemicalSystemType ) { case ChemicalSystemType::ultramafic: - m_numPrimarySpecies = 9; - m_numSecondarySpecies = 16; + m_numPrimarySpecies = 9; + m_numSecondarySpecies = 16; m_numKineticReactions = 5; break; case ChemicalSystemType::carbonate: - m_numPrimarySpecies = 7; - m_numSecondarySpecies = 10; + m_numPrimarySpecies = 7; + m_numSecondarySpecies = 10; m_numKineticReactions = 1; break; case ChemicalSystemType::carbonateAllEquilibrium: - m_numPrimarySpecies = 7; - m_numSecondarySpecies = 11; + m_numPrimarySpecies = 7; + m_numSecondarySpecies = 11; m_numKineticReactions = 0; break; @@ -103,14 +105,14 @@ void ReactiveSinglePhaseFluid< BASE >::postInputInitialization() break; case ChemicalSystemType::momasMedium: - m_numPrimarySpecies = 5; - m_numSecondarySpecies = 9; + m_numPrimarySpecies = 5; + m_numSecondarySpecies = 9; m_numKineticReactions = 1; break; default: - m_numPrimarySpecies = 5; - m_numSecondarySpecies = 7; + m_numPrimarySpecies = 5; + m_numSecondarySpecies = 7; m_numKineticReactions = 0; break; } diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp index e121c3528fd..6346d030c4f 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp @@ -158,13 +158,13 @@ class ReactiveSinglePhaseFluid : public BASE */ GEOS_HOST_DEVICE localIndex numElems() const { return m_secondarySpeciesConcentration.size( 0 ); } - + GEOS_HOST_DEVICE void updateEquilibriumReaction( localIndex const k, real64 const pressure, real64 const temperature, arraySlice1d< real64, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration ) const; - + GEOS_HOST_DEVICE void enforceEquilibrium( real64 const pressure, real64 const temperature, @@ -172,15 +172,15 @@ class ReactiveSinglePhaseFluid : public BASE arraySlice1d< real64 const, reactivefluid::USD_SPECIES - 2 > const & initialPrimarySpeciesConcentration, arraySlice1d< real64, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, arraySlice1d< real64 > const & logSecondarySpeciesConcentration ) const; - - GEOS_HOST_DEVICE + + GEOS_HOST_DEVICE void updateMixedReactionSystem( localIndex const k, real64 const pressure, real64 const temperature, arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & surfaceArea ) const; - GEOS_HOST_DEVICE + GEOS_HOST_DEVICE void computeAggregateConcentrationsAndRates( real64 const pressure, real64 const temperature, arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & logPrimarySpeciesConcentration, @@ -201,7 +201,7 @@ class ReactiveSinglePhaseFluid : public BASE integer m_numSecondarySpecies; - integer m_numKineticReactions; + integer m_numKineticReactions; arrayView3d< real64, reactivefluid::USD_SPECIES > m_primarySpeciesAggregateConcentration; @@ -253,7 +253,7 @@ class ReactiveSinglePhaseFluid : public BASE m_numSecondarySpecies, m_numKineticReactions, ultramaficSystem ); - + case ChemicalSystemType::carbonate: return ReactionKernelWrapper< carbonateSystemType >( m_primarySpeciesAggregateConcentration, m_primarySpeciesMobileAggregateConcentration, @@ -342,7 +342,7 @@ class ReactiveSinglePhaseFluid : public BASE integer m_numSecondarySpecies; - integer m_numKineticReactions; + integer m_numKineticReactions; array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_initialPrimarySpeciesConcentration; @@ -418,7 +418,7 @@ enforceEquilibrium( real64 const pressure, GEOS_UNUSED_VAR( pressure ); integer const numPrimarySpecies = m_numPrimarySpecies; - + stackArray1d< real64, MAX_NUM_SPECIES > logPrimarySpeciesConcentration0( numPrimarySpecies ); stackArray1d< real64, MAX_NUM_SPECIES > targetPrimarySpeciesAggregateConc( numPrimarySpecies ); @@ -427,7 +427,7 @@ enforceEquilibrium( real64 const pressure, targetPrimarySpeciesAggregateConc[i] = targetPrimarySpeciesAggregateConcentration[i]; logPrimarySpeciesConcentration0[i] = LvArray::math::log( initialPrimarySpeciesConcentration[i] ); } - + // 1. We enforce equilibrium EquilibriumReactionsType::enforceEquilibrium_Aggregate( temperature, m_params, targetPrimarySpeciesAggregateConc, logPrimarySpeciesConcentration0, logPrimarySpeciesConcentration ); @@ -451,11 +451,11 @@ updateMixedReactionSystem( localIndex const k, integer const numPrimarySpecies = m_numPrimarySpecies; integer const numSecondarySpecies = m_numSecondarySpecies; integer const numKineticReactions = m_numKineticReactions; - + stackArray1d< real64, MAX_NUM_SPECIES > logSecondarySpeciesConcentration( numSecondarySpecies ); stackArray2d< real64, MAX_NUM_KINETIC_REACTIONS * MAX_NUM_SPECIES > dReactionRates_dLogPrimarySpeciesConcentrations( numKineticReactions, numPrimarySpecies ); - - computeAggregateConcentrationsAndRates( pressure, + + computeAggregateConcentrationsAndRates( pressure, temperature, logPrimarySpeciesConcentration, surfaceArea, diff --git a/src/coreComponents/constitutive/solid/ReactiveSolid.hpp b/src/coreComponents/constitutive/solid/ReactiveSolid.hpp index 19f8d4dabd9..5e06af85ef3 100644 --- a/src/coreComponents/constitutive/solid/ReactiveSolid.hpp +++ b/src/coreComponents/constitutive/solid/ReactiveSolid.hpp @@ -49,8 +49,8 @@ class ReactiveSolidUpdates : public CoupledSolidUpdates< NullModel, PORO_TYPE, P * @brief Constructor */ ReactiveSolidUpdates( NullModel const & solidModel, - PORO_TYPE const & porosityModel, - PERM_TYPE const & permModel ): + PORO_TYPE const & porosityModel, + PERM_TYPE const & permModel ): CoupledSolidUpdates< NullModel, PORO_TYPE, PERM_TYPE >( solidModel, porosityModel, permModel ) {} @@ -78,11 +78,11 @@ class ReactiveSolidUpdates : public CoupledSolidUpdates< NullModel, PORO_TYPE, P { real64 const volumeFraction_r = m_porosityUpdate.getVolumeFractionForMineral( k, q, r ); real64 const initialVolumeFraction_r = m_porosityUpdate.getInitialVolumeFractionForMineral( k, q, r ); - surfaceArea[r] = initialSurfaceArea[r] * pow( volumeFraction_r / initialVolumeFraction_r, 2.0/3.0 ) - * pow( porosity / initialPorosity, 2.0/3.0 ); + surfaceArea[r] = initialSurfaceArea[r] * pow( volumeFraction_r / initialVolumeFraction_r, 2.0/3.0 ) + * pow( porosity / initialPorosity, 2.0/3.0 ); } } - + private: using CoupledSolidUpdates< NullModel, ReactivePorosity, PERM_TYPE >::m_solidUpdate; using CoupledSolidUpdates< NullModel, ReactivePorosity, PERM_TYPE >::m_porosityUpdate; diff --git a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp index 241b43d08b7..7865764fd7c 100644 --- a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp +++ b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.cpp @@ -74,13 +74,13 @@ void ReactivePorosity::postInputInitialization() PorosityBase::postInputInitialization(); GEOS_THROW_IF_NE_MSG( m_molarWeights.size(), m_defaultInitialVolumeFractions.size(), - GEOS_FMT( "{}: mismatch in number of components in porosity model attribute '{}' and '{}", - getFullName(), viewKeyStruct::molarWeightsString(), viewKeyStruct::initialVolumeFractionsString() ), + GEOS_FMT( "{}: mismatch in number of components in porosity model attribute '{}' and '{}", + getFullName(), viewKeyStruct::molarWeightsString(), viewKeyStruct::initialVolumeFractionsString() ), InputError ); GEOS_THROW_IF_NE_MSG( m_mineralDensities.size(), m_defaultInitialVolumeFractions.size(), - GEOS_FMT( "{}: mismatch in number of components in porosity model attribute '{}' and '{}", - getFullName(), viewKeyStruct::mineralDensitiesString(), viewKeyStruct::initialVolumeFractionsString() ), + GEOS_FMT( "{}: mismatch in number of components in porosity model attribute '{}' and '{}", + getFullName(), viewKeyStruct::mineralDensitiesString(), viewKeyStruct::initialVolumeFractionsString() ), InputError ); m_numKineticReactions = m_defaultInitialVolumeFractions.size(); @@ -112,7 +112,7 @@ void ReactivePorosity::saveConvergedState() const } void ReactivePorosity::initializeState() const -{ +{ integer const numKineticReactions = this->numKineticReactions(); for( localIndex ei = 0; ei < m_newPorosity.size( 0 ); ++ei ) @@ -131,9 +131,9 @@ void ReactivePorosity::initializeState() const { for( integer r = 0; r < numKineticReactions; ++r ) { - m_volumeFractions[ei][q][r] = m_defaultInitialVolumeFractions[r]; - m_initialVolumeFractions[ei][q][r] = m_defaultInitialVolumeFractions[r]; - m_volumeFractions_n[ei][q][r] = m_defaultInitialVolumeFractions[r]; + m_volumeFractions[ei][q][r] = m_defaultInitialVolumeFractions[r]; + m_initialVolumeFractions[ei][q][r] = m_defaultInitialVolumeFractions[r]; + m_volumeFractions_n[ei][q][r] = m_defaultInitialVolumeFractions[r]; } } } diff --git a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp index 43985b1a3cf..7fd28285423 100644 --- a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp +++ b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp @@ -68,22 +68,22 @@ class ReactivePorosityUpdates : public PorosityBaseUpdates integer const & numKineticReactions, arrayView1d< real64 const > const & molarWeights, arrayView1d< real64 const > const & mineralDensities ) const - { - real64 porosityIncrement = 0.0; + { + real64 porosityIncrement = 0.0; for( integer r=0; r < numKineticReactions; ++r ) { real64 const volumeFractionIncrement = kineticReactionMolarIncrements[r] * molarWeights[r]/mineralDensities[r]; - volumeFractions[r] = volumeFractions_n[r] + volumeFractionIncrement; + volumeFractions[r] = volumeFractions_n[r] + volumeFractionIncrement; - porosityIncrement += volumeFractionIncrement; + porosityIncrement += volumeFractionIncrement; } - porosity = porosity_n + porosityIncrement; // To check if it should be plus or minus + porosity = porosity_n + porosityIncrement; // To check if it should be plus or minus - if( porosity < 0) + if( porosity < 0 ) { - porosity = 0; + porosity = 0; } else if( porosity > 1.0 ) { @@ -131,8 +131,8 @@ class ReactivePorosityUpdates : public PorosityBaseUpdates arrayView3d< real64 const, reactivefluid::USD_SPECIES > m_initialVolumeFractions; arrayView3d< real64 const, reactivefluid::USD_SPECIES > const m_volumeFractions_n; - integer const m_numKineticReactions; - arrayView1d< real64 const > const m_molarWeights; + integer const m_numKineticReactions; + arrayView1d< real64 const > const m_molarWeights; arrayView1d< real64 const > const m_mineralDensities; }; @@ -203,9 +203,9 @@ class ReactivePorosity : public PorosityBase array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_volumeFractions; array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_initialVolumeFractions; array3d< real64, constitutive::reactivefluid::LAYOUT_SPECIES > m_volumeFractions_n; - - integer m_numKineticReactions; - array1d< real64 > m_molarWeights; + + integer m_numKineticReactions; + array1d< real64 > m_molarWeights; array1d< real64 > m_mineralDensities; }; diff --git a/src/coreComponents/integrationTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp b/src/coreComponents/integrationTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp index 313972c4ffb..25074a146e9 100644 --- a/src/coreComponents/integrationTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/integrationTests/fluidFlowTests/testSinglePhaseReactiveTransport.cpp @@ -494,7 +494,7 @@ class SinglePhaseReactiveTransportTest : public ::testing::Test { public: -SinglePhaseReactiveTransportTest(): + SinglePhaseReactiveTransportTest(): state( std::make_unique< CommandLineOptions >( g_commandLineOptions ) ) {} diff --git a/src/coreComponents/integrationTests/fluidFlowTests/testSinglePhaseReactiveTransportUtils.hpp b/src/coreComponents/integrationTests/fluidFlowTests/testSinglePhaseReactiveTransportUtils.hpp index beda1857853..2cd58eeb87d 100644 --- a/src/coreComponents/integrationTests/fluidFlowTests/testSinglePhaseReactiveTransportUtils.hpp +++ b/src/coreComponents/integrationTests/fluidFlowTests/testSinglePhaseReactiveTransportUtils.hpp @@ -103,7 +103,7 @@ void fillCellCenteredNumericalJacobian( SINGLE_REACTIVE_TRANSPORT_SOLVER & solve LAMBDA assembleFunction ) { integer const numSpecies = solver.numPrimarySpecies(); - + DofManager const & dofManager = solver.getDofManager(); string const elemDofKey = dofManager.getKey( SINGLE_REACTIVE_TRANSPORT_SOLVER::viewKeyStruct::elemDofFieldString() ); @@ -189,23 +189,23 @@ void fillCellCenteredNumericalJacobian( SINGLE_REACTIVE_TRANSPORT_SOLVER & solve } // Step 3: compute numerical derivatives wrt log primary species concentration - for( integer is = 0; is < numSpecies; ++is ) + for( integer is = 0; is < numSpecies; ++is ) { solver.resetStateToBeginningOfStep( domain ); logPrimaryConc.move( hostMemorySpace, true ); // to get the correct logPrimaryConc after reset real64 const dConc = perturbParameter * ( logPrimaryConc[ei][is] + perturbParameter ); - logPrimaryConc[ei][is] += dConc; + logPrimaryConc[ei][is] += dConc; #if defined(GEOS_USE_CUDA) logPrimaryConc.move( parallelDeviceMemorySpace, false ); -#endif +#endif solver.updateState( domain ); residual.zero(); jacobian.zero(); assembleFunction( jacobian.toViewConstSizes(), residual.toView() ); - integer const speciesIndexShift = (isThermal)? 2:1; + integer const speciesIndexShift = (isThermal)? 2:1; fillNumericalJacobian( residual.toViewConst(), residualOrig.toViewConst(), diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index c2ba3b9e8b8..806bdcb8d58 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -130,7 +130,7 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) if( m_reactiveFluidModelName.empty() ) { m_reactiveFluidModelName = m_isThermal? getConstitutiveName< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion ): - getConstitutiveName< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion ); + getConstitutiveName< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion ); } // If at least one region has a diffusion model, consider it enabled for all @@ -148,7 +148,8 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) { if( m_isThermal ) { - reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid const & reactiveFluid = cm.getConstitutiveRelation< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( m_reactiveFluidModelName ); + reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid const & reactiveFluid = cm.getConstitutiveRelation< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( + m_reactiveFluidModelName ); m_numPrimarySpecies = reactiveFluid.numPrimarySpecies(); m_numKineticReactions = reactiveFluid.numKineticReactions(); } @@ -203,15 +204,15 @@ void SinglePhaseReactiveTransport::registerDataOnMesh( Group & meshBodies ) subRegion.registerField< bcLogPrimarySpeciesConcentration >( getName() ). reference().resizeDimension< 1 >( m_numPrimarySpecies ); - + subRegion.registerField< kineticReactionMolarIncrements >( getName() ). reference().resizeDimension< 1 >( m_numKineticReactions ); subRegion.registerField< surfaceArea >( getName() ). - reference().resizeDimension< 1 >( m_numKineticReactions ); - + reference().resizeDimension< 1 >( m_numKineticReactions ); + subRegion.registerField< initialSurfaceArea >( getName() ). - reference().resizeDimension< 1 >( m_numKineticReactions ); + reference().resizeDimension< 1 >( m_numKineticReactions ); } ); } ); } @@ -281,7 +282,7 @@ void SinglePhaseReactiveTransport::resetStateToBeginningOfStep( DomainPartition logPrimarySpeciesConc.setValues< parallelDevicePolicy<> >( logPrimarySpeciesConc_n ); } ); } ); - + SinglePhaseBase::resetStateToBeginningOfStep( domain ); forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, @@ -304,7 +305,7 @@ void SinglePhaseReactiveTransport::implicitStepSetup( real64 const & time_n, GEOS_MARK_FUNCTION; SinglePhaseBase::implicitStepSetup( time_n, dt, domain ); - + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, string_array const & regionNames ) @@ -459,7 +460,7 @@ void SinglePhaseReactiveTransport::assembleFluxTerms( real64 const dt, mobilePrimarySpeciesFlags[immobileSpeciesIndex] = 0; } } - + forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &, MeshLevel const & mesh, string_array const & ) @@ -522,7 +523,7 @@ void SinglePhaseReactiveTransport::updateState( DomainPartition & domain ) auto & subRegion ) { updateMixedReactionSystem( subRegion ); - + updateSpeciesAmount( subRegion ); } ); } ); @@ -546,7 +547,7 @@ void SinglePhaseReactiveTransport::updateSpeciesAmount( ElementSubRegionBase & s if( m_isThermal ) { reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & fluid = - getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration_n = fluid.primarySpeciesAggregateConcentration_n(); @@ -564,7 +565,7 @@ void SinglePhaseReactiveTransport::updateSpeciesAmount( ElementSubRegionBase & s else { reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = - getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration_n = fluid.primarySpeciesAggregateConcentration_n(); @@ -591,7 +592,7 @@ void SinglePhaseReactiveTransport::updateKineticReactionMolarIncrements( real64 if( m_isThermal ) { reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & fluid = - getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); arrayView3d< real64 const, reactivefluid::USD_SPECIES > const kineticReactionRates = fluid.kineticReactionRates(); forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) @@ -605,7 +606,7 @@ void SinglePhaseReactiveTransport::updateKineticReactionMolarIncrements( real64 else { reactivefluid::ReactiveCompressibleSinglePhaseFluid & fluid = - getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); + getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); arrayView3d< real64 const, reactivefluid::USD_SPECIES > const kineticReactionRates = fluid.kineticReactionRates(); forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) @@ -750,14 +751,14 @@ void SinglePhaseReactiveTransport::initializeFluidState( MeshLevel & mesh, strin { reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid const & fluid = getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, fluidName ); - + fluid.initializeState(); } else { reactivefluid::ReactiveCompressibleSinglePhaseFluid const & fluid = getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, fluidName ); - + fluid.initializeState(); } @@ -988,7 +989,9 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ) ); arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); - arrayView4d< real64 const, reactivefluid::USD_SPECIES_DC > const dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations = fluid.dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations(); + arrayView4d< real64 const, + reactivefluid::USD_SPECIES_DC > const dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations = + fluid.dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations(); arrayView2d< real64 const, singlefluid::USD_FLUID > const density = fluid.density(); arrayView3d< real64 const, constitutive::singlefluid::USD_FLUID_DER > const dDensity = fluid.dDensity(); arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const enthalpy = fluid.enthalpy(); @@ -1014,7 +1017,7 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, singlePhaseReactiveBaseKernels::internal::kernelLaunchSelectorCompSwitch( numPrimarySpecies, [&] ( auto NS ) { integer constexpr NUM_SPECIES = NS(); - + // we need to filter out ghosts here, because targetSet may contain them localIndex const ei = targetSet[a]; if( ghostRank[ei] >= 0 ) @@ -1026,11 +1029,13 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, globalIndex const massRowIndex = dofNumber[ei] - rankOffset; globalIndex const energyRowIndex = massRowIndex + 1; globalIndex const speciesRowBeginIndex = massRowIndex + 2; - real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here! + real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor + // here! localRhs[massRowIndex] += rhsValue; massProd += rhsValue; - // add the value to the energy balance equation and species mass balance equations if the flux is positive (i.e., it's a producer) + // add the value to the energy balance equation and species mass balance equations if the flux is positive (i.e., it's a + // producer) if( rhsContributionArrayView[a] > 0.0 ) { globalIndex const pressureDofIndex = dofNumber[ei] - rankOffset; @@ -1038,28 +1043,28 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, globalIndex dofIndices[2+NUM_SPECIES]{}; - dofIndices[0] = pressureDofIndex; - dofIndices[1] = temperatureDofIndex; + dofIndices[0] = pressureDofIndex; + dofIndices[1] = temperatureDofIndex; for( integer i = 0; i < NUM_SPECIES; ++i ) { - dofIndices[i+2] = pressureDofIndex + i + 2; - } + dofIndices[i+2] = pressureDofIndex + i + 2; + } // add the value to the energy balance equation localRhs[energyRowIndex] += enthalpy[ei][0] * rhsValue; real64 jacobianEnergyFlux[2+NUM_SPECIES]{0.0}; - + jacobianEnergyFlux[0] = rhsValue * dEnthalpy[ei][0][DerivOffset::dP]; jacobianEnergyFlux[1] = rhsValue * dEnthalpy[ei][0][DerivOffset::dT]; localMatrix.template addToRow< serialAtomic >( energyRowIndex, - dofIndices, - jacobianEnergyFlux, - 2+NUM_SPECIES ); - - // add the value to the species mass balance equations + dofIndices, + jacobianEnergyFlux, + 2+NUM_SPECIES ); + + // add the value to the species mass balance equations for( integer i = 0; i < NUM_SPECIES; ++i ) { localRhs[speciesRowBeginIndex + i] += primarySpeciesAggregateConcentration[ei][0][i] / density[ei][0] * rhsValue; @@ -1074,9 +1079,9 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, } localMatrix.template addToRow< serialAtomic >( speciesRowBeginIndex + i, - dofIndices, - jacobianSpeciesFlux, - 2+NUM_SPECIES ); + dofIndices, + jacobianSpeciesFlux, + 2+NUM_SPECIES ); } } } ); @@ -1089,7 +1094,9 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ) ); arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); - arrayView4d< real64 const, reactivefluid::USD_SPECIES_DC > const dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations = fluid.dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations(); + arrayView4d< real64 const, + reactivefluid::USD_SPECIES_DC > const dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations = + fluid.dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations(); arrayView2d< real64 const, singlefluid::USD_FLUID > const density = fluid.density(); arrayView3d< real64 const, constitutive::singlefluid::USD_FLUID_DER > const dDensity = fluid.dDensity(); @@ -1122,7 +1129,8 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, // add the value to the mass balance equation globalIndex const massRowIndex = dofNumber[ei] - rankOffset; globalIndex const speciesRowBeginIndex = massRowIndex + 1; - real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here! + real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor + // here! localRhs[massRowIndex] += rhsValue; massProd += rhsValue; @@ -1133,12 +1141,12 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, globalIndex dofIndices[1+NUM_SPECIES]{}; - dofIndices[0] = pressureDofIndex; + dofIndices[0] = pressureDofIndex; for( integer i = 0; i < NUM_SPECIES; ++i ) { - dofIndices[i+1] = pressureDofIndex + i + 1; - } + dofIndices[i+1] = pressureDofIndex + i + 1; + } for( integer i = 0; i < NUM_SPECIES; ++i ) { @@ -1153,12 +1161,12 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, } localMatrix.template addToRow< serialAtomic >( speciesRowBeginIndex + i, - dofIndices, - jacobian, - 1+NUM_SPECIES ); + dofIndices, + jacobian, + 1+NUM_SPECIES ); } } - } ); + } ); } ); } @@ -1639,19 +1647,19 @@ void SinglePhaseReactiveTransport::applyFaceDirichletBC( real64 const time_n, BoundaryStencilWrapper const stencilWrapper = stencil.createKernelWrapper(); thermalSinglePhaseReactiveFVMKernels:: - DirichletFluxComputeKernelFactory:: - createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, - mobilePrimarySpeciesFlags, - dofManager.rankOffset(), - dofKey, - this->getName(), - faceManager, - elemManager, - stencilWrapper, - reactiveFluid, - dt, - localMatrix, - localRhs ); + DirichletFluxComputeKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, + mobilePrimarySpeciesFlags, + dofManager.rankOffset(), + dofKey, + this->getName(), + faceManager, + elemManager, + stencilWrapper, + reactiveFluid, + dt, + localMatrix, + localRhs ); } ); } else @@ -1690,19 +1698,19 @@ void SinglePhaseReactiveTransport::applyFaceDirichletBC( real64 const time_n, BoundaryStencilWrapper const stencilWrapper = stencil.createKernelWrapper(); singlePhaseReactiveFVMKernels:: - DirichletFluxComputeKernelFactory:: - createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, - mobilePrimarySpeciesFlags, - dofManager.rankOffset(), - dofKey, - this->getName(), - faceManager, - elemManager, - stencilWrapper, - reactiveFluid, - dt, - localMatrix, - localRhs ); + DirichletFluxComputeKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, + mobilePrimarySpeciesFlags, + dofManager.rankOffset(), + dofKey, + this->getName(), + faceManager, + elemManager, + stencilWrapper, + reactiveFluid, + dt, + localMatrix, + localRhs ); } ); } } ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index 5acc21b56c5..92fad383f29 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -292,7 +292,7 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase /// the number of primary species in the fluid integer m_numPrimarySpecies; - /// the number of kinetic reactions + /// the number of kinetic reactions integer m_numKineticReactions; /// name of the reactive fluid constitutive model @@ -308,7 +308,7 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase integer m_isUpdateSurfaceArea; /// array to store the indices of immobile primary species - array1d< integer > m_immobilePrimarySpeciesIndices; + array1d< integer > m_immobilePrimarySpeciesIndices; private: @@ -368,4 +368,4 @@ void SinglePhaseReactiveTransport::applyFieldValue( real64 const & time_n, } /* namespace geos */ -#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVETRANSPORT_HPP_ \ No newline at end of file +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVETRANSPORT_HPP_ diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp index eb4262aae2a..28c72f5c170 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp @@ -97,15 +97,15 @@ DECLARE_FIELD( surfaceArea, 0, NOPLOT, WRITE_AND_READ, - "Surface area for surface reactions." ); - + "Surface area for surface reactions." ); + DECLARE_FIELD( initialSurfaceArea, "initialSurfaceArea", array2dLayoutComp, 0, NOPLOT, WRITE_AND_READ, - "Initial surface area for surface reactions." ); + "Initial surface area for surface reactions." ); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/DirichletFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/DirichletFluxComputeKernel.hpp index d05ea6e706f..000c4d0b254 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/DirichletFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/DirichletFluxComputeKernel.hpp @@ -224,7 +224,7 @@ class DirichletFluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKern real64 const mobility_up = mobility[k_up]; real64 const dMobility_dP_up = dMobility_dP[k_up]; - // Upwind density + // Upwind density real64 const dens_up = ( potDif >= 0 ) ? m_dens[er][esr][ei][0] : faceDens; real64 const dDens_dP_up = ( potDif >= 0 ) ? m_dDens[er][esr][ei][0][Deriv::dP] : 0.0; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ThermalDirichletFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ThermalDirichletFluxComputeKernel.hpp index e6db619c950..b8e863d9ac0 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ThermalDirichletFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/ThermalDirichletFluxComputeKernel.hpp @@ -205,7 +205,7 @@ class DirichletFluxComputeKernel : public singlePhaseFVMKernels::DirichletFluxCo real64 const & dDens_dP_up ) { GEOS_UNUSED_VAR( dens_up, dDens_dP_up ); - + // Compute the derivatives of the density wrt temperature real64 const dDens_dT = 0.5 * m_dDens[er][esr][ei][0][DerivOffset::dT]; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp index 240cd272b2b..28c3b1cc181 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/AccumulationKernels.hpp @@ -172,7 +172,9 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU // stack.dPoreVolume_dLogPrimaryConc[is] * m_density[ei][0]; // } - arraySlice2d< real64 const, constitutive::reactivefluid::USD_SPECIES_DC - 2 > dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations = m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[ei][0]; + arraySlice2d< real64 const, + constitutive::reactivefluid::USD_SPECIES_DC - + 2 > dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations = m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[ei][0]; arraySlice2d< real64 const, constitutive::reactivefluid::USD_SPECIES_DC - 2 > dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc = m_dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc[ei][0]; for( integer is = 0; is < numSpecies; ++is ) @@ -199,13 +201,13 @@ class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SU { stack.localJacobian[is+numEqn-numSpecies][js+numDof-numSpecies] = /* stack.dPoreVolume_dLogPrimaryConc[js] * m_primarySpeciesAggregateConcentration[ei][0][is] - + */stack.poreVolume * dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[is][js]; // To - // check - // if - // the - // permutation - // is - // consistent + + */stack.poreVolume * dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[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] ) * dPrimarySpeciesAggregateKineticRate_dLogPrimaryConc[is][js]; } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/DirichletFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/DirichletFluxComputeKernel.hpp index cdf9e9c2f5e..80ff9bce9ba 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/DirichletFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/DirichletFluxComputeKernel.hpp @@ -133,7 +133,8 @@ class DirichletFluxComputeKernel : public singlePhaseFVMKernels::DirichletFluxCo localRhs ), m_dMob_dLogPrimaryConc( reactiveSinglePhaseFlowAccessors.get( fields::flow::dMobility_dLogPrimaryConc {} ) ), m_primarySpeciesMobileAggregateConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::primarySpeciesMobileAggregateConcentration {} ) ), - m_dPrimarySpeciesMobileAggregateConc_dLogPrimaryConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations {} ) ), + m_dPrimarySpeciesMobileAggregateConc_dLogPrimaryConc( reactiveSinglePhaseFluidAccessors.get( + fields::reactivefluid::dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations {} ) ), m_mobilePrimarySpeciesFlags( mobilePrimarySpeciesFlags ) {} @@ -190,9 +191,9 @@ class DirichletFluxComputeKernel : public singlePhaseFVMKernels::DirichletFluxCo real64 speciesFlux[numSpecies]{}; real64 dSpeciesFlux_dP[numSpecies]{}; real64 dSpeciesFlux_dLogConc[numSpecies][numSpecies]{}; - + for( integer is = 0; is < numSpecies; ++is ) - { + { real64 const aggregateConc_i = m_primarySpeciesMobileAggregateConc[seri][sesri][sei][0][is]; speciesFlux[is] = aggregateConc_i / dens_up * fluxVal * mobility_up; @@ -238,7 +239,7 @@ class DirichletFluxComputeKernel : public singlePhaseFVMKernels::DirichletFluxCo { for( integer is = 0; is < numSpecies; ++is ) { - RAJA::atomicAdd( parallelDeviceAtomic{}, &AbstractBase::m_localRhs[localRow + numEqn - numSpecies + is], + RAJA::atomicAdd( parallelDeviceAtomic{}, &AbstractBase::m_localRhs[localRow + numEqn - numSpecies + is], stack.localFlux[numEqn - numSpecies + is] ); AbstractBase::m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic > @@ -249,7 +250,7 @@ class DirichletFluxComputeKernel : public singlePhaseFVMKernels::DirichletFluxCo } assemblyKernelOp( localRow ); - } ); + } ); } protected: @@ -318,7 +319,7 @@ class DirichletFluxComputeKernelFactory integer constexpr NUM_DOF = 1+NS(); integer constexpr NUM_EQN = 1+NS(); - using kernelType = DirichletFluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, typename FluidType::KernelWrapper, + using kernelType = DirichletFluxComputeKernel< NUM_SPECIES, NUM_EQN, NUM_DOF, typename FluidType::KernelWrapper, constitutive::CompressibleSinglePhaseFluid >; ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > > dofNumberAccessor = @@ -333,19 +334,19 @@ class DirichletFluxComputeKernelFactory typename kernelType::PermeabilityAccessors permeabilityAccessors( elemManager, solverName ); kernelType kernel( rankOffset, - faceManager, - stencilWrapper, - fluidWrapper, - dofNumberAccessor, - singlePhaseFlowAccessors, - reactiveFlowAccessors, - singlePhaseFluidAccessors, - reactiveFluidAccessors, - permeabilityAccessors, - mobilePrimarySpeciesFlags, - dt, - localMatrix, - localRhs ); + faceManager, + stencilWrapper, + fluidWrapper, + dofNumberAccessor, + singlePhaseFlowAccessors, + reactiveFlowAccessors, + singlePhaseFluidAccessors, + reactiveFluidAccessors, + permeabilityAccessors, + mobilePrimarySpeciesFlags, + dt, + localMatrix, + localRhs ); kernelType::template launch< POLICY >( stencilWrapper.size(), kernel ); } ); diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp index 49c6d4e18c0..a408c29aa0d 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/FluxComputeKernel.hpp @@ -153,7 +153,8 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E m_logPrimarySpeciesConc( reactiveSinglePhaseFlowAccessors.get( fields::flow::logPrimarySpeciesConcentration {} ) ), m_dMob_dLogPrimaryConc( reactiveSinglePhaseFlowAccessors.get( fields::flow::dMobility_dLogPrimaryConc {} ) ), m_primarySpeciesMobileAggregateConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::primarySpeciesMobileAggregateConcentration {} ) ), - m_dPrimarySpeciesMobileAggregateConc_dLogPrimaryConc( reactiveSinglePhaseFluidAccessors.get( fields::reactivefluid::dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations {} ) ), + m_dPrimarySpeciesMobileAggregateConc_dLogPrimaryConc( reactiveSinglePhaseFluidAccessors.get( + fields::reactivefluid::dPrimarySpeciesMobileAggregateConcentration_dLogPrimarySpeciesConcentrations {} ) ), m_diffusivity( diffusionAccessors.get( fields::diffusion::diffusivity {} ) ), m_dDiffusivity_dTemp( diffusionAccessors.get( fields::diffusion::dDiffusivity_dTemperature {} ) ), m_referencePorosity( porosityAccessors.get( fields::porosity::referencePorosity {} ) ), @@ -342,7 +343,7 @@ class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_E //***** calculation of flux ***** // loop over primary species for( integer is = 0; is < numSpecies; ++is ) - { + { // real64 dSpeciesGrad_i_dP[numFluxSupportPoints]{}; // Turn on if speciesGrad is pressure-dependent real64 dSpeciesGrad_i_dLogConc[numFluxSupportPoints][numSpecies]{}; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp index 4f3a75f74fa..7a87bdfbc50 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp @@ -214,7 +214,7 @@ class DirichletFluxComputeKernel : public singlePhaseReactiveFVMKernels::Dirichl real64 const & dF_dP, real64 const & mobility_up, real64 const & dMobility_dP_up ) - { + { // Compute the derivatives of the density wrt temperature real64 const dDens_dT = 0.5 * m_dDens[er][esr][ei][0][DerivOffset::dT]; @@ -282,7 +282,7 @@ class DirichletFluxComputeKernel : public singlePhaseReactiveFVMKernels::Dirichl { Base::complete( iconn, stack, [&] ( localIndex const localRow ) { - RAJA::atomicAdd( parallelDeviceAtomic{}, &AbstractBase::m_localRhs[localRow + numEqn - numSpecies - 1], + RAJA::atomicAdd( parallelDeviceAtomic{}, &AbstractBase::m_localRhs[localRow + numEqn - numSpecies - 1], stack.localFlux[numEqn - numSpecies - 1] ); AbstractBase::m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic > diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp index c9295829042..d436b261628 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp @@ -327,7 +327,7 @@ class FluxComputeKernel : public singlePhaseReactiveFVMKernels::FluxComputeKerne // Step 2.2: compute speciesFlux derivative wrt temperature for( integer is = 0; is < numSpecies; ++is ) - { + { real64 const aggregateConc_i = m_primarySpeciesMobileAggregateConc[er_up][esr_up][ei_up][0][is]; // real64 const dAggregateConc_i_dTemp = m_dPrimarySpeciesMobileAggregateConcentration_dTemp[er_up][esr_up][ei_up][is]; From 79450283379f754e002b9b0add417dee74865c0c Mon Sep 17 00:00:00 2001 From: Randolph Settgast Date: Thu, 23 Oct 2025 16:11:01 -0700 Subject: [PATCH 57/66] attempted workaround for cuda error --- .../reactive/ReactionUpdateKernel.hpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp index aaaede6d88e..7ab1d2c8481 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp @@ -35,6 +35,19 @@ namespace singlePhaseReactiveBaseKernels struct EquilibriumReactionUpdateKernel { + + template< typename REACTION_WRAPPER_TYPE > + static void helper( REACTION_WRAPPER_TYPE 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 ) + { + reactionWrapper.updateEquilibriumReaction( k, pres[k], temp[k], logPrimaryConc[k] ); + } ); + } + template< typename REACTIVE_FLUID > static void launch( REACTIVE_FLUID const & fluid, arrayView1d< real64 const > const & pres, @@ -43,10 +56,7 @@ struct EquilibriumReactionUpdateKernel { std::visit( [&]( auto const reactionWrapper ) { - forAll< parallelDevicePolicy<> >( reactionWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) - { - reactionWrapper.updateEquilibriumReaction( k, pres[k], temp[k], logPrimaryConc[k] ); - } ); + helper( reactionWrapper, pres, temp, logPrimaryConc ); }, fluid.createReactionKernelWrapper()); } }; From 78e4f45a2184ef38e75165804903cd45b5d921a7 Mon Sep 17 00:00:00 2001 From: "Randolph R. Settgast" Date: Thu, 23 Oct 2025 17:09:29 -0700 Subject: [PATCH 58/66] fix cuda compile issues --- .../reactive/ReactionUpdateKernel.hpp | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp index 7ab1d2c8481..d6f85f53698 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp @@ -42,10 +42,10 @@ struct EquilibriumReactionUpdateKernel arrayView1d< real64 const > const & temp, arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc ) { - forAll< parallelDevicePolicy<> >( reactionWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) - { - reactionWrapper.updateEquilibriumReaction( k, pres[k], temp[k], logPrimaryConc[k] ); - } ); + forAll< parallelDevicePolicy<> >( reactionWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) + { + reactionWrapper.updateEquilibriumReaction( k, pres[k], temp[k], logPrimaryConc[k] ); + } ); } template< typename REACTIVE_FLUID > @@ -54,7 +54,7 @@ struct EquilibriumReactionUpdateKernel arrayView1d< real64 const > const & temp, arrayView2d< real64, compflow::USD_COMP > const logPrimaryConc ) { - std::visit( [&]( auto const reactionWrapper ) + std::visit( [&]( auto const & reactionWrapper ) { helper( reactionWrapper, pres, temp, logPrimaryConc ); }, fluid.createReactionKernelWrapper()); @@ -65,6 +65,20 @@ struct EquilibriumReactionUpdateKernel struct MixedSystemReactionUpdateKernel { + + template< typename REACTION_WRAPPER_TYPE > + static void helper( REACTION_WRAPPER_TYPE const & reactionWrapper, + arrayView1d< real64 const > const & pres, + arrayView1d< real64 const > const & temp, + arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc, + arrayView2d< real64 const, compflow::USD_COMP > const surfaceArea ) + { + forAll< parallelDevicePolicy<> >( reactionWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) + { + reactionWrapper.updateMixedReactionSystem( k, pres[k], temp[k], logPrimaryConc[k], surfaceArea[k] ); + } ); + } + template< typename REACTIVE_FLUID > static void launch( REACTIVE_FLUID const & fluid, arrayView1d< real64 const > const & pres, @@ -72,12 +86,9 @@ struct MixedSystemReactionUpdateKernel arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc, arrayView2d< real64 const, compflow::USD_COMP > const surfaceArea ) { - std::visit( [&]( auto const reactionWrapper ) + std::visit( [&]( auto const & reactionWrapper ) { - forAll< parallelDevicePolicy<> >( reactionWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) - { - reactionWrapper.updateMixedReactionSystem( k, pres[k], temp[k], logPrimaryConc[k], surfaceArea[k] ); - } ); + helper( reactionWrapper, pres, temp, logPrimaryConc, surfaceArea ); }, fluid.createReactionKernelWrapper()); } }; From 1671d9f74a79394d31b39c0d7ad417f6c6e994e7 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Thu, 23 Oct 2025 17:42:44 -0700 Subject: [PATCH 59/66] fix compile --- .../kernels/singlePhase/reactive/ReactionUpdateKernel.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp index d6f85f53698..79496d888fe 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ReactionUpdateKernel.hpp @@ -40,7 +40,7 @@ struct EquilibriumReactionUpdateKernel static void helper( REACTION_WRAPPER_TYPE const & reactionWrapper, arrayView1d< real64 const > const & pres, arrayView1d< real64 const > const & temp, - arrayView2d< real64 const, compflow::USD_COMP > const logPrimaryConc ) + arrayView2d< real64, compflow::USD_COMP > const logPrimaryConc ) { forAll< parallelDevicePolicy<> >( reactionWrapper.numElems(), [=] GEOS_HOST_DEVICE ( localIndex const k ) { From 7ddb0a851926604ef34ba874c3d5a03d48015604 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Wed, 29 Oct 2025 14:25:28 -0700 Subject: [PATCH 60/66] initial chemomechanics coupling and an 1D example for simple testing --- .../ChemoMechanics_CarbonateSystem_base.xml | 139 ++++++++ ...s_CarbonateSystem_explicitUpdate_1DBar.xml | 85 +++++ ...anics_CarbonateSystem_initialAggregate.xml | 133 ++++++++ ...ics_CarbonateSystem_initialPrimaryConc.xml | 133 ++++++++ .../constitutive/CMakeLists.txt | 2 + .../constitutive/ConstitutivePassThru.hpp | 20 ++ .../constitutive/solid/CoupledSolid.hpp | 20 ++ .../solid/PorousReactiveSolid.cpp | 57 ++++ .../solid/PorousReactiveSolid.hpp | 315 ++++++++++++++++++ .../constitutive/solid/ReactiveSolid.hpp | 19 +- .../solid/porosity/ReactivePorosity.hpp | 14 + .../SinglePhaseReactiveTransport.cpp | 24 +- .../multiphysics/CoupledSolver.hpp | 8 +- .../multiphysics/PhaseFieldFractureSolver.cpp | 5 +- .../multiphysics/PhaseFieldFractureSolver.hpp | 2 +- .../PhaseFieldPoromechanicsSolver.cpp | 4 +- .../PhaseFieldPoromechanicsSolver.hpp | 2 +- .../PoromechanicsConformingFractures.hpp | 4 +- .../multiphysics/PoromechanicsSolver.hpp | 38 ++- .../multiphysics/SinglePhasePoromechanics.cpp | 27 ++ .../multiphysics/SinglePhasePoromechanics.hpp | 6 + .../solidMechanics/CMakeLists.txt | 5 +- .../SolidMechanicsLagrangianFEM.cpp | 26 +- .../SolidMechanicsLagrangianFEM.hpp | 5 + .../solidMechanics/kernelSpecs.json | 33 ++ .../kernels/ExplicitChemoMechanics.hpp | 239 +++++++++++++ .../kernels/ExplicitChemoMechanics_impl.hpp | 234 +++++++++++++ ...ExplicitChemoMechanicsKernels.cpp.template | 38 +++ .../solidMechanics/kernels/policies.hpp.in | 1 + 29 files changed, 1599 insertions(+), 39 deletions(-) create mode 100644 inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_base.xml create mode 100644 inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_explicitUpdate_1DBar.xml create mode 100644 inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_initialAggregate.xml create mode 100644 inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_initialPrimaryConc.xml create mode 100644 src/coreComponents/constitutive/solid/PorousReactiveSolid.cpp create mode 100644 src/coreComponents/constitutive/solid/PorousReactiveSolid.hpp create mode 100644 src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitChemoMechanics.hpp create mode 100644 src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitChemoMechanics_impl.hpp create mode 100644 src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsExplicitChemoMechanicsKernels.cpp.template diff --git a/inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_base.xml b/inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_base.xml new file mode 100644 index 00000000000..0f79543cf3a --- /dev/null +++ b/inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_base.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_explicitUpdate_1DBar.xml b/inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_explicitUpdate_1DBar.xml new file mode 100644 index 00000000000..d33afd9f178 --- /dev/null +++ b/inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_explicitUpdate_1DBar.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_initialAggregate.xml b/inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_initialAggregate.xml new file mode 100644 index 00000000000..1d5feb21230 --- /dev/null +++ b/inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_initialAggregate.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_initialPrimaryConc.xml b/inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_initialPrimaryConc.xml new file mode 100644 index 00000000000..8ce64e0159d --- /dev/null +++ b/inputFiles/chemoMechanics/ChemoMechanics_CarbonateSystem_initialPrimaryConc.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt index 68aa7fb980f..0f3409902f5 100644 --- a/src/coreComponents/constitutive/CMakeLists.txt +++ b/src/coreComponents/constitutive/CMakeLists.txt @@ -187,6 +187,7 @@ set( constitutive_headers solid/InvariantDecompositions.hpp solid/PorousDamageSolid.hpp solid/PerfectlyPlastic.hpp + solid/PorousReactiveSolid.hpp solid/PorousSolid.hpp solid/PropertyConversions.hpp solid/ReactiveSolid.hpp @@ -328,6 +329,7 @@ set( constitutive_sources solid/ElasticOrthotropic.cpp solid/PorousDamageSolid.cpp solid/PerfectlyPlastic.cpp + solid/PorousReactiveSolid.cpp solid/PorousSolid.cpp solid/ReactiveSolid.cpp solid/SolidBase.cpp diff --git a/src/coreComponents/constitutive/ConstitutivePassThru.hpp b/src/coreComponents/constitutive/ConstitutivePassThru.hpp index d5dc88018ab..1b8bd91fe79 100644 --- a/src/coreComponents/constitutive/ConstitutivePassThru.hpp +++ b/src/coreComponents/constitutive/ConstitutivePassThru.hpp @@ -36,6 +36,7 @@ #include "solid/ElasticIsotropicPressureDependent.hpp" #include "solid/ElasticTransverseIsotropic.hpp" #include "solid/ElasticOrthotropic.hpp" +#include "solid/PorousReactiveSolid.hpp" #include "solid/PorousSolid.hpp" #include "solid/PorousDamageSolid.hpp" #include "solid/CompressibleSolid.hpp" @@ -339,6 +340,21 @@ struct ConstitutivePassThru< PorousDamageSolidBase > } }; +/** + * Specialization for the PorousReactiveSolid models. + */ +template<> +struct ConstitutivePassThru< PorousReactiveSolidBase > +{ + template< typename LAMBDA > + static void execute( ConstitutiveBase & constitutiveRelation, LAMBDA && lambda ) + { + ConstitutivePassThruHandler< PorousReactiveSolid< ElasticIsotropic, ConstantPermeability >, + PorousReactiveSolid< ElasticIsotropic, CarmanKozenyPermeability > >::execute( constitutiveRelation, + std::forward< LAMBDA >( lambda ) ); + } +}; + /** * Specialization for the CompressibleSolid models. */ @@ -442,6 +458,8 @@ struct ConstitutivePassThru< CoupledSolidBase > CompressibleSolid< PressurePorosity, PressurePermeability >, CompressibleSolid< PressurePorosity, SlipDependentPermeability >, CompressibleSolid< PressurePorosity, WillisRichardsPermeability >, + PorousReactiveSolid< ElasticIsotropic, ConstantPermeability >, + PorousReactiveSolid< ElasticIsotropic, CarmanKozenyPermeability >, PorousSolid< DruckerPragerExtended, ConstantPermeability >, PorousSolid< ModifiedCamClay, ConstantPermeability >, PorousSolid< DelftEgg, ConstantPermeability >, @@ -483,6 +501,8 @@ struct ConstitutivePassThru< CoupledSolidBase > CompressibleSolid< PressurePorosity, PressurePermeability >, CompressibleSolid< PressurePorosity, SlipDependentPermeability >, CompressibleSolid< PressurePorosity, WillisRichardsPermeability >, + PorousReactiveSolid< ElasticIsotropic, ConstantPermeability >, + PorousReactiveSolid< ElasticIsotropic, CarmanKozenyPermeability >, PorousSolid< DruckerPragerExtended, ConstantPermeability >, PorousSolid< ModifiedCamClay, ConstantPermeability >, PorousSolid< DelftEgg, ConstantPermeability >, diff --git a/src/coreComponents/constitutive/solid/CoupledSolid.hpp b/src/coreComponents/constitutive/solid/CoupledSolid.hpp index 93e26caa84a..244c899fee7 100644 --- a/src/coreComponents/constitutive/solid/CoupledSolid.hpp +++ b/src/coreComponents/constitutive/solid/CoupledSolid.hpp @@ -22,6 +22,7 @@ #define GEOS_CONSTITUTIVE_SOLID_COUPLEDSOLID_HPP_ #include "constitutive/solid/CoupledSolidBase.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp" namespace geos { @@ -105,6 +106,25 @@ class CoupledSolidUpdates temperature, temperature_k, temperature_n ); } + GEOS_HOST_DEVICE + virtual void updateStateFromPressureTemperatureAndReactions( localIndex const k, + localIndex const q, + real64 const & pressure, + real64 const & temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & kineticReactionMolarIncrements ) const + { + GEOS_UNUSED_VAR( k, q, pressure, temperature, kineticReactionMolarIncrements ); + } + + GEOS_HOST_DEVICE + virtual void updateSurfaceArea( localIndex const k, + localIndex const q, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & initialSurfaceArea, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & surfaceArea ) const + { + GEOS_UNUSED_VAR( k, q, initialSurfaceArea, surfaceArea ); + } + GEOS_HOST_DEVICE virtual real64 getShearModulus( localIndex const k ) const { diff --git a/src/coreComponents/constitutive/solid/PorousReactiveSolid.cpp b/src/coreComponents/constitutive/solid/PorousReactiveSolid.cpp new file mode 100644 index 00000000000..fb36db2a959 --- /dev/null +++ b/src/coreComponents/constitutive/solid/PorousReactiveSolid.cpp @@ -0,0 +1,57 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 PorousReactiveSolid.cpp + */ + +#include "PorousReactiveSolid.hpp" +#include "ElasticIsotropic.hpp" +#include "constitutive/permeability/ConstantPermeability.hpp" +#include "constitutive/permeability/CarmanKozenyPermeability.hpp" + +namespace geos +{ + +using namespace dataRepository; + +namespace constitutive +{ + +template< typename SOLID_TYPE, + typename PERM_TYPE > +PorousReactiveSolid< SOLID_TYPE, PERM_TYPE >::PorousReactiveSolid( string const & name, Group * const parent ): + CoupledSolid< SOLID_TYPE, ReactivePorosity, PERM_TYPE >( name, parent ) +{} + +template< typename SOLID_TYPE, + typename PERM_TYPE > +void PorousReactiveSolid< SOLID_TYPE, PERM_TYPE >::initializeState() const +{ + CoupledSolid< SOLID_TYPE, ReactivePorosity, PERM_TYPE >::initializeState(); +} + +// Register all PorousReactiveSolid model types. +typedef PorousReactiveSolid< ElasticIsotropic, ConstantPermeability > PorousReactiveElasticIsotropicConstant; +typedef PorousReactiveSolid< ElasticIsotropic, CarmanKozenyPermeability > PorousReactiveElasticIsotropicCK; + + +REGISTER_CATALOG_ENTRY( ConstitutiveBase, PorousReactiveElasticIsotropicConstant, string const &, Group * const ) +REGISTER_CATALOG_ENTRY( ConstitutiveBase, PorousReactiveElasticIsotropicCK, string const &, Group * const ) + + +} +} /* namespace geos */ diff --git a/src/coreComponents/constitutive/solid/PorousReactiveSolid.hpp b/src/coreComponents/constitutive/solid/PorousReactiveSolid.hpp new file mode 100644 index 00000000000..ccebb893ea3 --- /dev/null +++ b/src/coreComponents/constitutive/solid/PorousReactiveSolid.hpp @@ -0,0 +1,315 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 PorousReactiveSolid.hpp + */ + +#ifndef GEOS_CONSTITUTIVE_SOLID_POROUSREACTIVESOLID_HPP_ +#define GEOS_CONSTITUTIVE_SOLID_POROUSREACTIVESOLID_HPP_ + +#include "constitutive/solid/CoupledSolid.hpp" +#include "constitutive/solid/porosity/ReactivePorosity.hpp" +#include "constitutive/solid/SolidBase.hpp" +#include "constitutive/permeability/ConstantPermeability.hpp" + +#include "constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp" + +namespace geos +{ +namespace constitutive +{ + +/** + * @brief Provides kernel-callable constitutive update routines + * + * + * @tparam SOLID_TYPE type of the porosity model + */ +template< typename SOLID_TYPE, + typename PERM_TYPE > +class PorousReactiveSolidUpdates : public CoupledSolidUpdates< SOLID_TYPE, ReactivePorosity, PERM_TYPE > +{ +public: + + using DiscretizationOps = typename SOLID_TYPE::KernelWrapper::DiscretizationOps; + + /** + * @brief Constructor + */ + PorousReactiveSolidUpdates( SOLID_TYPE const & solidModel, + ReactivePorosity const & porosityModel, + PERM_TYPE const & permModel ): + CoupledSolidUpdates< SOLID_TYPE, ReactivePorosity, PERM_TYPE >( solidModel, porosityModel, permModel ) + {} + + GEOS_HOST_DEVICE + virtual void updateStateFromPressureTemperatureAndReactions( localIndex const k, + localIndex const q, + real64 const & pressure, + real64 const & temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & kineticReactionMolarIncrements ) const override final + { + GEOS_UNUSED_VAR( temperature ); + + m_porosityUpdate.updateFromReactions( k, q, kineticReactionMolarIncrements ); + real64 const porosity = m_porosityUpdate.getPorosity( k, q ); + m_permUpdate.updateFromPressureAndPorosity( k, q, pressure, porosity ); + } + + GEOS_HOST_DEVICE + virtual void updateSurfaceArea( localIndex const k, + localIndex const q, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & initialSurfaceArea, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & surfaceArea ) const override final + { + real64 const porosity = m_porosityUpdate.getPorosity( k, q ); + real64 const initialPorosity = m_porosityUpdate.getInitialPorosity( k, q ); + + for( integer r=0; r < initialSurfaceArea.size(); ++r ) + { + real64 const volumeFraction_r = m_porosityUpdate.getVolumeFractionForMineral( k, q, r ); + real64 const initialVolumeFraction_r = m_porosityUpdate.getInitialVolumeFractionForMineral( k, q, r ); + surfaceArea[r] = initialSurfaceArea[r] * pow( volumeFraction_r / initialVolumeFraction_r, 2.0/3.0 ) + * pow( porosity / initialPorosity, 2.0/3.0 ); + } + } + + GEOS_HOST_DEVICE + void smallStrainUpdateExplicitChemoMechanics( localIndex const k, + localIndex const q, + real64 const & timeIncrement, + real64 const & pressure, + real64 const & pressure_n, + real64 const & temperature, + real64 const & temperature_n, + real64 const & referenceTemperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > mineralReactionMolarIncrements, + real64 const ( &strainIncrement )[6], + real64 ( & totalStress )[6], + DiscretizationOps & stiffness ) const + { + GEOS_UNUSED_VAR( pressure_n, referenceTemperature ); + + real64 anelasticStrainIncrement = 0.0; + + for( integer r=0; r < mineralReactionMolarIncrements.size(); ++r ) + { + real64 const molarWeight = m_porosityUpdate.getMolarWeights( r ); + real64 const mineralDensity = m_porosityUpdate.getMineralDensities( r ); + + anelasticStrainIncrement -= mineralReactionMolarIncrements[r] * molarWeight/mineralDensity; + + // std::cout << "mineralReactionMolarIncrements[" << r << "] = " << mineralReactionMolarIncrements[r] << std::endl + // << "molarWeight[" << r << "] = " << molarWeight << std::endl + // << "mineralDensity[" << r << "] = " << mineralDensity << std::endl; + } + + // Compute total stress increment and its derivative + real64 const deltaTemperatureFromLastStep = temperature - temperature_n; + computeTotalStress( k, + q, + timeIncrement, + pressure, + deltaTemperatureFromLastStep, + anelasticStrainIncrement, + strainIncrement, + totalStress, + stiffness ); + } + + /** + * @brief Return the stiffness at a given element (small-strain interface) + * + * @note If the material model has a strain-dependent material stiffness (e.g. + * any plasticity, damage, or nonlinear elastic model) then this interface will + * not work. Users should instead use one of the interfaces where a strain + * tensor is provided as input. + * + * @param k the element number + * @param stiffness the stiffness array + */ + GEOS_HOST_DEVICE + inline + void getElasticStiffness( localIndex const k, localIndex const q, real64 ( & stiffness )[6][6] ) const + { + m_solidUpdate.getElasticStiffness( k, q, stiffness ); + } + + /** + * @brief Return the stiffness at a given element (small-strain interface) + * + * @param [in] k the element number + * @param [out] thermalExpansionCoefficient the thermal expansion coefficient + */ + GEOS_HOST_DEVICE + inline + void getThermalExpansionCoefficient( localIndex const k, real64 & thermalExpansionCoefficient ) const + { + thermalExpansionCoefficient = m_solidUpdate.getThermalExpansionCoefficient( k ); + } + +private: + + using CoupledSolidUpdates< SOLID_TYPE, ReactivePorosity, PERM_TYPE >::m_solidUpdate; + using CoupledSolidUpdates< SOLID_TYPE, ReactivePorosity, PERM_TYPE >::m_porosityUpdate; + using CoupledSolidUpdates< SOLID_TYPE, ReactivePorosity, PERM_TYPE >::m_permUpdate; + + GEOS_HOST_DEVICE + inline + void computeTotalStress( localIndex const k, + localIndex const q, + real64 const & timeIncrement, + real64 const & pressure, + real64 const & deltaTemperatureFromLastStep, + real64 const & anelasticStrainIncrement, + real64 const ( &strainIncrement )[6], + real64 ( & totalStress )[6], + DiscretizationOps & stiffness ) const + { + real64 const thermalExpansionCoefficient = m_solidUpdate.getThermalExpansionCoefficient( k ); + + // std::cout << "anelasticStrainIncrement = " << anelasticStrainIncrement << std::endl; + + real64 mechanicsStrainIncrement[6]{}; + mechanicsStrainIncrement[0] = strainIncrement[0] - thermalExpansionCoefficient * deltaTemperatureFromLastStep - anelasticStrainIncrement; + mechanicsStrainIncrement[1] = strainIncrement[1] - thermalExpansionCoefficient * deltaTemperatureFromLastStep - anelasticStrainIncrement; + mechanicsStrainIncrement[2] = strainIncrement[2] - thermalExpansionCoefficient * deltaTemperatureFromLastStep - anelasticStrainIncrement; + mechanicsStrainIncrement[3] = strainIncrement[3]; + mechanicsStrainIncrement[4] = strainIncrement[4]; + mechanicsStrainIncrement[5] = strainIncrement[5]; + + // Compute total stress increment and its derivative w.r.t. pressure + m_solidUpdate.smallStrainUpdate( k, + q, + timeIncrement, + mechanicsStrainIncrement, + totalStress, // first effective stress increment accumulated + stiffness ); + + // Add the contributions of pressure to the total stress + LvArray::tensorOps::symAddIdentity< 3 >( totalStress, -pressure ); + + } + +}; + +/** + * @brief PorousReactiveSolidBase class used for dispatch of all Porous solids. + */ +class PorousReactiveSolidBase +{}; + +/** + * @brief Class to represent a porous material for poromechanics simulations. + * It is used as an interface to access all constitutive models relative to the properties of a porous material. + * + * @tparam SOLID_TYPE type of solid model + */ +template< typename SOLID_TYPE, + typename PERM_TYPE > +class PorousReactiveSolid : public CoupledSolid< SOLID_TYPE, ReactivePorosity, PERM_TYPE > +{ +public: + + /// Alias for ElasticIsotropicUpdates + using KernelWrapper = PorousReactiveSolidUpdates< SOLID_TYPE, PERM_TYPE >; + + /** + * @brief Constructor + * @param name Object name + * @param parent Object's parent group + */ + PorousReactiveSolid( string const & name, dataRepository::Group * const parent ); + + /** + * @brief Catalog name + * @return Static catalog string + */ + static string catalogName() + { + if constexpr ( std::is_same_v< PERM_TYPE, ConstantPermeability > ) // default case + { + return string( "PorousReactive" ) + SOLID_TYPE::catalogName(); + } + else // special cases + { + return string( "PorousReactive" ) + SOLID_TYPE::catalogName() + PERM_TYPE::catalogName(); + } + } + + /** + * @brief Get catalog name + * @return Catalog name string + */ + virtual string getCatalogName() const override { return catalogName(); } + + /** + * @brief Create a instantiation of the PorousReactiveSolidUpdates class + * that refers to the data in this. + * @return An instantiation of PorousReactiveSolidUpdates. + */ + KernelWrapper createKernelUpdates() const + { + return KernelWrapper( getSolidModel(), + getPorosityModel(), + getPermModel() ); + } + + /** + * @brief initialize the constitutive models fields. + */ + virtual void initializeState() const override final; + + /** + * @brief Const/non-mutable accessor for density + * @return Accessor + */ + arrayView2d< real64 const > const getDensity() const + { + return getSolidModel().getDensity(); + } + + /** + * @brief Const/non-mutable accessor for the mean stress increment at the previous sequential iteration + * @return Accessor + */ + arrayView2d< real64 const > const getMeanStressIncrement_k() const + { + return getPorosityModel().getMeanStressIncrement_k(); + } + + /** + * @brief Non-const accessor for the mean stress increment at the previous sequential iteration + * @return Accessor + */ + arrayView1d< real64 > const getAverageMeanStressIncrement_k() + { + return getPorosityModel().getAverageMeanStressIncrement_k(); + } + +private: + using CoupledSolid< SOLID_TYPE, ReactivePorosity, PERM_TYPE >::getSolidModel; + using CoupledSolid< SOLID_TYPE, ReactivePorosity, PERM_TYPE >::getPorosityModel; + using CoupledSolid< SOLID_TYPE, ReactivePorosity, PERM_TYPE >::getPermModel; +}; + + + +} +} /* namespace geos */ + +#endif /* GEOS_CONSTITUTIVE_SOLID_POROUSREACTIVESOLID_HPP_ */ diff --git a/src/coreComponents/constitutive/solid/ReactiveSolid.hpp b/src/coreComponents/constitutive/solid/ReactiveSolid.hpp index 5e06af85ef3..2c489ba92b5 100644 --- a/src/coreComponents/constitutive/solid/ReactiveSolid.hpp +++ b/src/coreComponents/constitutive/solid/ReactiveSolid.hpp @@ -55,21 +55,24 @@ class ReactiveSolidUpdates : public CoupledSolidUpdates< NullModel, PORO_TYPE, P {} GEOS_HOST_DEVICE - void updateStateFromPressureAndReactions( localIndex const k, - localIndex const q, - real64 const & pressure, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & kineticReactionMolarIncrements ) const + virtual void updateStateFromPressureTemperatureAndReactions( localIndex const k, + localIndex const q, + real64 const & pressure, + real64 const & temperature, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & kineticReactionMolarIncrements ) const override final { + GEOS_UNUSED_VAR( temperature ); + m_porosityUpdate.updateFromReactions( k, q, kineticReactionMolarIncrements ); real64 const porosity = m_porosityUpdate.getPorosity( k, q ); m_permUpdate.updateFromPressureAndPorosity( k, q, pressure, porosity ); } GEOS_HOST_DEVICE - void updateSurfaceArea( localIndex const k, - localIndex const q, - arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & initialSurfaceArea, - arraySlice1d< real64, compflow::USD_COMP - 1 > const & surfaceArea ) const + virtual void updateSurfaceArea( localIndex const k, + localIndex const q, + arraySlice1d< real64 const, compflow::USD_COMP - 1 > const & initialSurfaceArea, + arraySlice1d< real64, compflow::USD_COMP - 1 > const & surfaceArea ) const override final { real64 const porosity = m_porosityUpdate.getPorosity( k, q ); real64 const initialPorosity = m_porosityUpdate.getInitialPorosity( k, q ); diff --git a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp index 7fd28285423..adafd421783 100644 --- a/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp +++ b/src/coreComponents/constitutive/solid/porosity/ReactivePorosity.hpp @@ -125,6 +125,20 @@ class ReactivePorosityUpdates : public PorosityBaseUpdates return m_initialVolumeFractions[k][q][r]; } + GEOS_HOST_DEVICE + inline + real64 getMolarWeights( localIndex const r ) const + { + return m_molarWeights[r]; + } + + GEOS_HOST_DEVICE + inline + real64 getMineralDensities( localIndex const r ) const + { + return m_mineralDensities[r]; + } + protected: arrayView3d< real64, reactivefluid::USD_SPECIES > m_volumeFractions; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 3097325009e..23fe8454a38 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -47,18 +47,20 @@ using namespace dataRepository; using namespace constitutive; template< typename POROUSWRAPPER_TYPE > -void updatePorosityAndPermeabilityFromPressureAndReactions( POROUSWRAPPER_TYPE porousWrapper, - ElementSubRegionBase & subRegion, - arrayView1d< real64 const > const & pressure, - arrayView2d< real64 const, compflow::USD_COMP > const & kineticReactionMolarIncrements ) +void updatePorosityAndPermeabilityFromPressureTemperatureAndReactions( POROUSWRAPPER_TYPE porousWrapper, + ElementSubRegionBase & subRegion, + arrayView1d< real64 const > const & pressure, + arrayView1d< real64 const > const & temperature, + arrayView2d< real64 const, compflow::USD_COMP > const & kineticReactionMolarIncrements ) { forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_DEVICE ( localIndex const k ) { for( localIndex q = 0; q < porousWrapper.numGauss(); ++q ) { - porousWrapper.updateStateFromPressureAndReactions( k, q, - pressure[k], - kineticReactionMolarIncrements[k] ); + porousWrapper.updateStateFromPressureTemperatureAndReactions( k, q, + pressure[k], + temperature[k], + kineticReactionMolarIncrements[k] ); } } ); } @@ -588,7 +590,6 @@ void SinglePhaseReactiveTransport::updateKineticReactionMolarIncrements( real64 GEOS_MARK_FUNCTION; arrayView2d< real64, compflow::USD_COMP > const kineticReactionMolarIncrements = subRegion.getField< fields::flow::kineticReactionMolarIncrements >(); - if( m_isThermal ) { reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & fluid = @@ -658,15 +659,16 @@ void SinglePhaseReactiveTransport::updatePorosityAndPermeability( CellElementSub if( m_isUpdateReactivePorosity ) { arrayView1d< real64 const > const & pressure = subRegion.getField< fields::flow::pressure >(); + arrayView1d< real64 const > const & temperature = subRegion.getField< fields::flow::temperature >(); arrayView2d< real64 const, compflow::USD_COMP > const kineticReactionMolarIncrements = subRegion.getField< fields::flow::kineticReactionMolarIncrements >(); string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); CoupledSolidBase & porousSolid = subRegion.template getConstitutiveModel< CoupledSolidBase >( solidName ); - constitutive::ConstitutivePassThru< ReactiveSolidBase >::execute( porousSolid, [=, &subRegion] ( auto & castedPorousSolid ) + constitutive::ConstitutivePassThru< CoupledSolidBase >::execute( porousSolid, [=, &subRegion] ( auto & castedPorousSolid ) { typename TYPEOFREF( castedPorousSolid ) ::KernelWrapper porousWrapper = castedPorousSolid.createKernelUpdates(); - updatePorosityAndPermeabilityFromPressureAndReactions( porousWrapper, subRegion, pressure, kineticReactionMolarIncrements ); + updatePorosityAndPermeabilityFromPressureTemperatureAndReactions( porousWrapper, subRegion, pressure, temperature, kineticReactionMolarIncrements ); } ); } else @@ -720,7 +722,7 @@ void SinglePhaseReactiveTransport::updateSurfaceArea( ElementSubRegionBase & sub string const & solidName = subRegion.getReference< string >( viewKeyStruct::solidNamesString() ); CoupledSolidBase & porousSolid = subRegion.template getConstitutiveModel< CoupledSolidBase >( solidName ); - constitutive::ConstitutivePassThru< ReactiveSolidBase >::execute( porousSolid, [=, &subRegion] ( auto & castedPorousSolid ) + constitutive::ConstitutivePassThru< CoupledSolidBase >::execute( porousSolid, [=, &subRegion] ( auto & castedPorousSolid ) { typename TYPEOFREF( castedPorousSolid ) ::KernelWrapper porousWrapper = castedPorousSolid.createKernelUpdates(); updateSurfaceAreaFromReactions( porousWrapper, subRegion, initialSurfaceArea, surfaceArea ); diff --git a/src/coreComponents/physicsSolvers/multiphysics/CoupledSolver.hpp b/src/coreComponents/physicsSolvers/multiphysics/CoupledSolver.hpp index 333220bff67..300088cf592 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/CoupledSolver.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/CoupledSolver.hpp @@ -511,7 +511,7 @@ class CoupledSolver : public PhysicsSolverBase solver->saveSequentialIterationState( domain ); } - mapSolutionBetweenSolvers( domain, idx() ); + mapSolutionBetweenSolvers( stepDt, domain, idx() ); if( solverDt < stepDt ) // subsolver had to cut the time step { @@ -588,13 +588,15 @@ class CoupledSolver : public PhysicsSolverBase /** * @brief Maps the solution obtained from one solver to the fields used by the other solver(s) * + * @param dt timestep size * @param domain the domain partition * @param solverType the index of the solver withing this coupled solver. */ - virtual void mapSolutionBetweenSolvers( DomainPartition & domain, + virtual void mapSolutionBetweenSolvers( real64 const & dt, + DomainPartition & domain, integer const solverType ) { - GEOS_UNUSED_VAR( domain, solverType ); + GEOS_UNUSED_VAR( dt, domain, solverType ); } virtual bool checkSequentialConvergence( integer const cycleNumber, diff --git a/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldFractureSolver.cpp b/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldFractureSolver.cpp index 751dd7dea77..033929e4fd3 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldFractureSolver.cpp +++ b/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldFractureSolver.cpp @@ -50,9 +50,10 @@ void PhaseFieldFractureSolver::postInputInitialization() getNonlinearSolverParameters().m_couplingType = NonlinearSolverParameters::CouplingType::Sequential; } -void PhaseFieldFractureSolver::mapSolutionBetweenSolvers( DomainPartition & domain, integer const solverType ) +void PhaseFieldFractureSolver::mapSolutionBetweenSolvers( real64 const & dt, DomainPartition & domain, integer const solverType ) { - + GEOS_UNUSED_VAR( dt ); + GEOS_MARK_FUNCTION; if( solverType == static_cast< integer >( SolverType::Damage ) ) { diff --git a/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldFractureSolver.hpp b/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldFractureSolver.hpp index a1aae598694..af63526d7ca 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldFractureSolver.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldFractureSolver.hpp @@ -86,7 +86,7 @@ class PhaseFieldFractureSolver : public CoupledSolver< SolidMechanicsLagrangianF return std::get< toUnderlying( SolverType::Damage ) >( m_solvers ); } - virtual void mapSolutionBetweenSolvers( DomainPartition & Domain, integer const idx ) override final; + virtual void mapSolutionBetweenSolvers( real64 const & dt, DomainPartition & Domain, integer const idx ) override final; protected: diff --git a/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldPoromechanicsSolver.cpp b/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldPoromechanicsSolver.cpp index 06bb5259f06..e18a7343cf7 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldPoromechanicsSolver.cpp +++ b/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldPoromechanicsSolver.cpp @@ -57,8 +57,10 @@ PhaseFieldPoromechanicsSolver::~PhaseFieldPoromechanicsSolver() // TODO Auto-generated destructor stub } -void PhaseFieldPoromechanicsSolver::mapSolutionBetweenSolvers( DomainPartition & domain, integer const solverType ) +void PhaseFieldPoromechanicsSolver::mapSolutionBetweenSolvers( real64 const & dt, DomainPartition & domain, integer const solverType ) { + GEOS_UNUSED_VAR( dt ); + if( solverType == static_cast< integer >( SolverType::Damage ) ) { GEOS_MARK_FUNCTION; diff --git a/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldPoromechanicsSolver.hpp b/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldPoromechanicsSolver.hpp index 359f428a3c3..76eac71b4c3 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldPoromechanicsSolver.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/PhaseFieldPoromechanicsSolver.hpp @@ -87,7 +87,7 @@ class PhaseFieldPoromechanicsSolver : public CoupledSolver< SinglePhasePoromecha return std::get< toUnderlying( SolverType::Damage ) >( m_solvers ); } - virtual void mapSolutionBetweenSolvers( DomainPartition & Domain, integer const idx ) override final; + virtual void mapSolutionBetweenSolvers( real64 const & dt, DomainPartition & Domain, integer const idx ) override final; void mapDamageAndGradientToQuadrature( DomainPartition & domain ); diff --git a/src/coreComponents/physicsSolvers/multiphysics/PoromechanicsConformingFractures.hpp b/src/coreComponents/physicsSolvers/multiphysics/PoromechanicsConformingFractures.hpp index 2366f915fd4..5a25e5241ec 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/PoromechanicsConformingFractures.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/PoromechanicsConformingFractures.hpp @@ -564,7 +564,7 @@ class PoromechanicsConformingFractures : public POROMECHANICS_BASE< FLOW_SOLVER, CRSMatrixView< real64, globalIndex const > const & localMatrix, arrayView1d< real64 > const & localRhs ) = 0; - virtual void mapSolutionBetweenSolvers( DomainPartition & domain, integer const solverType ) override + virtual void mapSolutionBetweenSolvers( real64 const & dt, DomainPartition & domain, integer const solverType ) override { GEOS_MARK_FUNCTION; @@ -581,7 +581,7 @@ class PoromechanicsConformingFractures : public POROMECHANICS_BASE< FLOW_SOLVER, this->flowSolver()->updateStencilWeights( domain ); } - Base::mapSolutionBetweenSolvers( domain, solverType ); + Base::mapSolutionBetweenSolvers( dt, domain, solverType ); } void updateHydraulicApertureAndFracturePermeability( DomainPartition & domain ) diff --git a/src/coreComponents/physicsSolvers/multiphysics/PoromechanicsSolver.hpp b/src/coreComponents/physicsSolvers/multiphysics/PoromechanicsSolver.hpp index f553759e327..ffabe0a92ad 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/PoromechanicsSolver.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/PoromechanicsSolver.hpp @@ -127,6 +127,12 @@ class PoromechanicsSolver : public CoupledSolver< FLOW_SOLVER, MECHANICS_SOLVER EnumStrings< SolidMechanicsLagrangianFEM::TimeIntegrationOption >::toString( SolidMechanicsLagrangianFEM::TimeIntegrationOption::QuasiStatic ) ), InputError ); + GEOS_THROW_IF( this->flowSolver()->getCatalogName() == "SinglePhaseReactiveTransport" && + this->getNonlinearSolverParameters().m_couplingType != NonlinearSolverParameters::CouplingType::Sequential, + GEOS_FMT( "{} {}: The coupling type must be Sequential since it is coupled with {}", + this->getCatalogName(), this->getName(), this->flowSolver()->getCatalogName() ), + InputError ); + setMGRStrategy(); } @@ -186,10 +192,18 @@ class PoromechanicsSolver : public CoupledSolver< FLOW_SOLVER, MECHANICS_SOLVER if( this->getNonlinearSolverParameters().m_couplingType == NonlinearSolverParameters::CouplingType::Sequential ) { - // to let the solid mechanics solver that there is a pressure and temperature RHS in the mechanics solve - solidMechanicsSolver()->enableFixedStressPoromechanicsUpdate(); - // to let the flow solver that saving pressure_k and temperature_k is necessary (for the fixed-stress porosity terms) - flowSolver()->enableFixedStressPoromechanicsUpdate(); + if( flowSolver()->getCatalogName() == "SinglePhaseReactiveTransport" ) + { + // to let the solid mechanics solver to account for anelastic strain due to chemistry + solidMechanicsSolver()->enableExplicitChemomechanicsUpdate(); + } + else + { + // to let the solid mechanics solver that there is a pressure and temperature RHS in the mechanics solve + solidMechanicsSolver()->enableFixedStressPoromechanicsUpdate(); + // to let the flow solver that saving pressure_k and temperature_k is necessary (for the fixed-stress porosity terms) + flowSolver()->enableFixedStressPoromechanicsUpdate(); + } } if( m_stabilizationType == stabilization::StabilizationType::Global || m_stabilizationType == stabilization::StabilizationType::Local ) @@ -649,8 +663,10 @@ class PoromechanicsSolver : public CoupledSolver< FLOW_SOLVER, MECHANICS_SOLVER } } - virtual void mapSolutionBetweenSolvers( DomainPartition & domain, integer const solverType ) override + virtual void mapSolutionBetweenSolvers( real64 const & dt, DomainPartition & domain, integer const solverType ) override { + GEOS_UNUSED_VAR( dt ); + GEOS_MARK_FUNCTION; /// After the flow solver @@ -663,8 +679,11 @@ class PoromechanicsSolver : public CoupledSolver< FLOW_SOLVER, MECHANICS_SOLVER if( solverType == static_cast< integer >( SolverType::SolidMechanics ) && !m_performStressInitialization ) // do not update during poromechanics initialization { - // compute the average of the mean total stress increment over quadrature points - averageMeanTotalStressIncrement( domain ); + if( flowSolver()->getCatalogName() != "SinglePhaseReactiveTransport" ) // For now, Biot Poromechanics is not considered for ChemoMechanics + { + // compute the average of the mean total stress increment over quadrature points + averageMeanTotalStressIncrement( domain ); + } this->template forDiscretizationOnMeshTargets<>( domain.getMeshBodies(), [&]( string const &, MeshLevel & mesh, @@ -687,7 +706,10 @@ class PoromechanicsSolver : public CoupledSolver< FLOW_SOLVER, MECHANICS_SOLVER if( solverType == static_cast< integer >( SolverType::SolidMechanics ) && this->getNonlinearSolverParameters().m_nonlinearAccelerationType== NonlinearSolverParameters::NonlinearAccelerationType::Aitken ) { - recordAverageMeanTotalStressIncrement( domain, m_s2_tilde ); + if( flowSolver()->getCatalogName() != "SinglePhaseReactiveTransport" ) // For now, Biot Poromechanics is not considered for ChemoMechanics + { + recordAverageMeanTotalStressIncrement( domain, m_s2_tilde ); + } } } diff --git a/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.cpp b/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.cpp index 7a3fdc6386a..c8ecaadc617 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.cpp +++ b/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.cpp @@ -179,6 +179,30 @@ void SinglePhasePoromechanics< SinglePhaseReservoirAndWells<>, SolidMechanicsLag flowSolver()->assembleCouplingTerms( time_n, dt, domain, dofManager, localMatrix, localRhs ); } +template<> +void SinglePhasePoromechanics< SinglePhaseReactiveTransport, SolidMechanicsLagrangianFEM >::mapSolutionBetweenSolvers( real64 const & dt, + DomainPartition & domain, + integer const solverType ) +{ + GEOS_MARK_FUNCTION; + + Base::mapSolutionBetweenSolvers( dt, domain, solverType ); + + if( solverType == static_cast< integer >( SolverType::Flow ) ) + { + this->template forDiscretizationOnMeshTargets<>( domain.getMeshBodies(), [&]( string const &, + MeshLevel & mesh, + string_array const & regionNames ) + { + mesh.getElemManager().forElementSubRegions( regionNames, [&]( localIndex const, + ElementSubRegionBase & subRegion ) + { + flowSolver()->updateKineticReactionMolarIncrements( dt, subRegion ); + } ); + } ); + } +} + template< typename FLOW_SOLVER, typename MECHANICS_SOLVER > void SinglePhasePoromechanics< FLOW_SOLVER, MECHANICS_SOLVER >::assembleElementBasedTerms( real64 const time_n, real64 const dt, @@ -347,9 +371,12 @@ template class SinglePhasePoromechanics< SinglePhaseBase, SolidMechanicsEmbedded template class SinglePhasePoromechanics< SinglePhaseReservoirAndWells<> >; template class SinglePhasePoromechanics< SinglePhaseReservoirAndWells<>, SolidMechanicsLagrangeContact >; //template class SinglePhasePoromechanics< SinglePhaseReservoirAndWells<>, SolidMechanicsEmbeddedFractures >; +template class SinglePhasePoromechanics< SinglePhaseReactiveTransport >; namespace { +typedef SinglePhasePoromechanics< SinglePhaseReactiveTransport > SinglePhaseChemomechanics; +REGISTER_CATALOG_ENTRY( PhysicsSolverBase, SinglePhaseChemomechanics, string const &, Group * const ) typedef SinglePhasePoromechanics< SinglePhaseReservoirAndWells<> > SinglePhaseReservoirPoromechanics; REGISTER_CATALOG_ENTRY( PhysicsSolverBase, SinglePhaseReservoirPoromechanics, string const &, Group * const ) typedef SinglePhasePoromechanics<> SinglePhasePoromechanics; diff --git a/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.hpp b/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.hpp index 0c564bf3d23..e9d0cc9d7ff 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.hpp +++ b/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.hpp @@ -22,6 +22,7 @@ #include "physicsSolvers/multiphysics/PoromechanicsSolver.hpp" #include "physicsSolvers/fluidFlow/SinglePhaseBase.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp" #include "physicsSolvers/multiphysics/SinglePhaseReservoirAndWells.hpp" namespace geos @@ -97,6 +98,11 @@ class SinglePhasePoromechanics : public PoromechanicsSolver< FLOW_SOLVER, MECHAN arrayView1d< real64 > const & localRhs ) override { Base::assembleSystem( time, dt, domain, dofManager, localMatrix, localRhs ); } + virtual void mapSolutionBetweenSolvers( real64 const & dt, + DomainPartition & domain, + integer const solverType ) override + { Base::mapSolutionBetweenSolvers( dt, domain, solverType ); } + virtual void assembleElementBasedTerms( real64 const time_n, real64 const dt, DomainPartition & domain, diff --git a/src/coreComponents/physicsSolvers/solidMechanics/CMakeLists.txt b/src/coreComponents/physicsSolvers/solidMechanics/CMakeLists.txt index ced15c47ba5..c399776c304 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/CMakeLists.txt +++ b/src/coreComponents/physicsSolvers/solidMechanics/CMakeLists.txt @@ -25,6 +25,8 @@ set( solidMechanicsSolvers_headers kernels/SolidMechanicsLagrangianFEMKernels.hpp SolidMechanicsMPM.hpp MPMSolverFields.hpp + kernels/ExplicitChemoMechanics.hpp + kernels/ExplicitChemoMechanics_impl.hpp kernels/ExplicitFiniteStrain.hpp kernels/ExplicitFiniteStrain_impl.hpp kernels/ExplicitMPM.hpp @@ -82,7 +84,8 @@ set( kernelTemplateFileList "" ) list( APPEND kernelTemplateFileList kernels/SolidMechanicsKernels.cpp.template - kernels/SolidMechanicsFixedStressThermoPoromechanicsKernels.cpp.template ) + kernels/SolidMechanicsFixedStressThermoPoromechanicsKernels.cpp.template + kernels/SolidMechanicsExplicitChemoMechanicsKernels.cpp.template ) foreach( kernelTemplateFile ${kernelTemplateFileList} ) diff --git a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp index f3dd742fa6d..d1c5bfce738 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.cpp @@ -25,6 +25,7 @@ #include "kernels/ExplicitSmallStrain.hpp" #include "kernels/ExplicitFiniteStrain.hpp" #include "kernels/FixedStressThermoPoromechanics.hpp" +#include "kernels/ExplicitChemoMechanics.hpp" #include "common/GEOS_RAJA_Interface.hpp" #include "constitutive/ConstitutiveManager.hpp" @@ -48,6 +49,7 @@ #include "physicsSolvers/LogLevelsInfo.hpp" #include "physicsSolvers/solidMechanics/kernels/SolidMechanicsKernelsDispatchTypeList.hpp" #include "physicsSolvers/solidMechanics/kernels/SolidMechanicsFixedStressThermoPoromechanicsKernelsDispatchTypeList.hpp" +#include "physicsSolvers/solidMechanics/kernels/SolidMechanicsExplicitChemoMechanicsKernelsDispatchTypeList.hpp" #include "physicsSolvers/fluidFlow/FlowSolverBase.hpp" namespace geos @@ -69,7 +71,8 @@ SolidMechanicsLagrangianFEM::SolidMechanicsLagrangianFEM( const string & name, m_maxNumResolves( 10 ), m_strainTheory( 0 ), m_isFixedStressPoromechanicsUpdate( false ), - m_performStressInitialization( false ) + m_performStressInitialization( false ), + m_isExplicitChemomechanicsUpdate( false ) { registerWrapper( viewKeyStruct::newmarkGammaString(), &m_newmarkGamma ). @@ -1132,6 +1135,22 @@ void SolidMechanicsLagrangianFEM::assembleSystem( real64 const GEOS_UNUSED_PARAM m_maxForce = LvArray::math::max( mechanicsMaxForce, poromechanicsMaxForce ); } + else if( m_isExplicitChemomechanicsUpdate ) + { + + // first pass for coupled poromechanics regions + real64 const chemomechanicsMaxForce= assemblyLaunch< SolidMechanicsExplicitChemoMechanicsKernelsDispatchTypeList, + solidMechanicsLagrangianFEMKernels::ExplicitChemoMechanicsFactory >( mesh, + dofManager, + regionNames, + FlowSolverBase::viewKeyStruct::solidNamesString(), + localMatrix, + localRhs, + dt ); + + + m_maxForce = chemomechanicsMaxForce; + } else { if( m_timeIntegrationOption == TimeIntegrationOption::QuasiStatic ) @@ -1508,6 +1527,11 @@ void SolidMechanicsLagrangianFEM::enableFixedStressPoromechanicsUpdate() m_isFixedStressPoromechanicsUpdate = true; } +void SolidMechanicsLagrangianFEM::enableExplicitChemomechanicsUpdate() +{ + m_isExplicitChemomechanicsUpdate = true; +} + void SolidMechanicsLagrangianFEM::saveSequentialIterationState( DomainPartition & GEOS_UNUSED_PARAM( domain ) ) { // nothing to save diff --git a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.hpp b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.hpp index de4c7630f42..3f1d0b777fe 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.hpp +++ b/src/coreComponents/physicsSolvers/solidMechanics/SolidMechanicsLagrangianFEM.hpp @@ -226,6 +226,8 @@ class SolidMechanicsLagrangianFEM : public PhysicsSolverBase void enableFixedStressPoromechanicsUpdate(); + void enableExplicitChemomechanicsUpdate(); + virtual void saveSequentialIterationState( DomainPartition & domain ) override; struct viewKeyStruct : PhysicsSolverBase::viewKeyStruct @@ -307,6 +309,9 @@ class SolidMechanicsLagrangianFEM : public PhysicsSolverBase /// Flag to indicate that the solver is going to perform stress initialization bool m_performStressInitialization; + /// Flag to indicate that the solver is running with explicit chemomechancis update + bool m_isExplicitChemomechanicsUpdate; + /// Rigid body modes; TODO remove mutable hack mutable array1d< ParallelVector > m_rigidBodyModes; diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernelSpecs.json b/src/coreComponents/physicsSolvers/solidMechanics/kernelSpecs.json index ca527443f5a..84824c78ec5 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernelSpecs.json +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernelSpecs.json @@ -29,6 +29,7 @@ "constants": [ [ "ExplicitSmallStrainPolicy", "geos::parallelDevicePolicy< GEOS_BLOCK_SIZE >" ], [ "ExplicitFiniteStrainPolicy", "geos::parallelDevicePolicy< GEOS_BLOCK_SIZE >" ], + [ "ExplicitChemoMechanicsPolicy", "geos::parallelDevicePolicy< GEOS_BLOCK_SIZE >" ], [ "FixedStressThermoPoromechanicsPolicy", "geos::parallelDevicePolicy< GEOS_BLOCK_SIZE >" ], [ "ImplicitSmallStrainNewmarkPolicy", "geos::parallelDevicePolicy< GEOS_BLOCK_SIZE >" ], [ "ImplicitSmallStrainQuasiStaticPolicy", "geos::parallelDevicePolicy< GEOS_BLOCK_SIZE >" ] @@ -144,5 +145,37 @@ ] }, "explicit": [] + }, + + "SolidMechanicsExplicitChemoMechanicsKernels": { + "vars": [ + "SUBREGION_TYPE", + "CONSTITUTIVE_TYPE", + "FE_TYPE" + ], + "constants": [ + [ "ExplicitSmallStrainPolicy", "geos::parallelDevicePolicy< GEOS_BLOCK_SIZE >" ], + [ "ExplicitFiniteStrainPolicy", "geos::parallelDevicePolicy< GEOS_BLOCK_SIZE >" ], + [ "ExplicitChemoMechanicsPolicy", "geos::parallelDevicePolicy< GEOS_BLOCK_SIZE >" ], + [ "FixedStressThermoPoromechanicsPolicy", "geos::parallelDevicePolicy< GEOS_BLOCK_SIZE >" ], + [ "ImplicitSmallStrainNewmarkPolicy", "geos::parallelDevicePolicy< GEOS_BLOCK_SIZE >" ], + [ "ImplicitSmallStrainQuasiStaticPolicy", "geos::parallelDevicePolicy< GEOS_BLOCK_SIZE >" ] + ], + "combinations": { + "SUBREGION_TYPE": [ + "CellElementSubRegion" + ], + "CONSTITUTIVE_TYPE": [ + "PorousReactiveSolid", + "PorousReactiveSolid" + ], + "FE_TYPE": [ + "H1_Hexahedron_Lagrange1_GaussLegendre2", + "H1_Wedge_Lagrange1_Gauss6", + "H1_Tetrahedron_Lagrange1_Gauss1", + "H1_Pyramid_Lagrange1_Gauss5" + ] + }, + "explicit": [] } } diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitChemoMechanics.hpp b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitChemoMechanics.hpp new file mode 100644 index 00000000000..c0321447f26 --- /dev/null +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitChemoMechanics.hpp @@ -0,0 +1,239 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ExplicitChemoMechanics.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_EXPLICITCHEMOMECHANICS_HPP_ +#define GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_EXPLICITCHEMOMECHANICS_HPP_ + +#include "finiteElement/kernelInterface/ImplicitKernelBase.hpp" + +namespace geos +{ + +namespace solidMechanicsLagrangianFEMKernels +{ + +/** + * @brief Implements kernels for solving the solid part of the chemomechanics problem. + * @copydoc geos::finiteElement::ImplicitKernelBase + * @tparam NUM_NODES_PER_ELEM The number of nodes per element for the + * @p SUBREGION_TYPE. + * @tparam UNUSED An unused parameter since we are assuming that the test and + * trial space have the same number of support points. + * + * ### ExplicitChemoMechanics Description + * Implements the KernelBase interface functions required for using the + * effective stress for the integration of the stress divergence. This is + * templated on one of the "finite element kernel application" functions + * such as geos::finiteElement::RegionBasedKernelApplication. + */ +template< typename SUBREGION_TYPE, + typename CONSTITUTIVE_TYPE, + typename FE_TYPE > +class ExplicitChemoMechanics : + public finiteElement::ImplicitKernelBase< SUBREGION_TYPE, + CONSTITUTIVE_TYPE, + FE_TYPE, + 3, + 3 > +{ +public: + /// Alias for the base class; + using Base = finiteElement::ImplicitKernelBase< SUBREGION_TYPE, + CONSTITUTIVE_TYPE, + FE_TYPE, + 3, + 3 >; + + /// Maximum number of nodes per element, which is equal to the maxNumTestSupportPointPerElem and + /// maxNumTrialSupportPointPerElem by definition. When the FE_TYPE is not a Virtual Element, this + /// will be the actual number of nodes per element. + static constexpr int numNodesPerElem = Base::maxNumTestSupportPointsPerElem; + using Base::numDofPerTestSupportPoint; + using Base::numDofPerTrialSupportPoint; + using Base::m_dofNumber; + using Base::m_dofRankOffset; + using Base::m_matrix; + using Base::m_rhs; + using Base::m_elemsToNodes; + using Base::m_constitutiveUpdate; + using Base::m_finiteElementSpace; + using Base::m_meshData; + using Base::m_dt; + + /** + * @brief Constructor + * @copydoc geos::finiteElement::ImplicitKernelBase::ImplicitKernelBase + * @param inputGravityVector The gravity vector. + */ + ExplicitChemoMechanics( NodeManager const & nodeManager, + EdgeManager const & edgeManager, + FaceManager const & faceManager, + localIndex const targetRegionIndex, + SUBREGION_TYPE const & elementSubRegion, + FE_TYPE const & finiteElementSpace, + CONSTITUTIVE_TYPE & inputConstitutiveType, + arrayView1d< globalIndex const > const inputDofNumber, + globalIndex const rankOffset, + CRSMatrixView< real64, globalIndex const > const inputMatrix, + arrayView1d< real64 > const inputRhs, + real64 const inputDt, + real64 const (&inputGravityVector)[3] ); + + //***************************************************************************** + /** + * @class StackVariables + * @copydoc geos::finiteElement::ImplicitKernelBase::StackVariables + * + * Adds a stack array for the displacement, incremental displacement, and the + * constitutive stiffness. + */ + struct StackVariables : public Base::StackVariables + { +public: + + /// Constructor. + GEOS_HOST_DEVICE + StackVariables(): + Base::StackVariables(), + xLocal(), + u_local(), + uhat_local(), + constitutiveStiffness() + {} + +#if !defined(CALC_FEM_SHAPE_IN_KERNEL) + /// Dummy + int xLocal; +#else + /// C-array stack storage for element local the nodal positions. + real64 xLocal[ numNodesPerElem ][ 3 ]; +#endif + + /// Stack storage for the element local nodal displacement + real64 u_local[numNodesPerElem][numDofPerTrialSupportPoint]; + + /// Stack storage for the element local nodal incremental displacement + real64 uhat_local[numNodesPerElem][numDofPerTrialSupportPoint]; + + /// Stack storage for the constitutive stiffness at a quadrature point. + real64 constitutiveStiffness[ 6 ][ 6 ]; + }; + //***************************************************************************** + + /** + * @brief Copy global values from primary field to a local stack array. + * @copydoc ::geos::finiteElement::ImplicitKernelBase::setup + * + * For the ExplicitChemoMechanics implementation, global values from the displacement, + * incremental displacement, and degree of freedom numbers are placed into + * element local stack storage. + */ + GEOS_HOST_DEVICE + void setup( localIndex const k, + StackVariables & stack ) const; + + /** + * @copydoc geos::finiteElement::KernelBase::quadraturePointKernel + * For solid mechanics kernels, the strain increment is calculated, and the + * constitutive update is called. In addition, the constitutive stiffness + * stack variable is filled by the constitutive model. + */ + GEOS_HOST_DEVICE + void quadraturePointKernel( localIndex const k, + localIndex const q, + StackVariables & stack ) const; + + /** + * @copydoc geos::finiteElement::ImplicitKernelBase::complete + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + real64 complete( localIndex const k, + StackVariables & stack ) const; + + /** + * @copydoc geos::finiteElement::KernelBase::kernelLaunch + */ + template< typename POLICY, + typename KERNEL_TYPE > + static real64 + kernelLaunch( localIndex const numElems, + KERNEL_TYPE const & kernelComponent ); + +protected: + /// The array containing the nodal position array. + arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const m_X; + + /// The rank-global displacement array. + arrayView2d< real64 const, nodes::TOTAL_DISPLACEMENT_USD > const m_disp; + + /// The rank-global incremental displacement array. + arrayView2d< real64 const, nodes::INCR_DISPLACEMENT_USD > const m_uhat; + + /// The gravity vector. + real64 const m_gravityVector[3]; + + /// The rank global bulk density + arrayView2d< real64 const > const m_bulkDensity; + + /// The rank-global fluid pressure arrays. + arrayView1d< real64 const > const m_pressure; + arrayView1d< real64 const > const m_pressure_n; + + /// The rank-global initial temperature array + arrayView1d< real64 const > const m_initialTemperature; + + /// The rank-global temperature arrays. + arrayView1d< real64 const > const m_temperature; + arrayView1d< real64 const > const m_temperature_n; + + /// The rank-global mineral reaction molar increments arrays. + arrayView2d< real64 const, compflow::USD_COMP > const m_mineralReactionMolarIncrements; + + /** + * @brief Get a parameter representative of the stiffness, used as physical scaling for the + * stabilization matrix. + * @param[in] k Element index. + * @return A parameter representative of the stiffness matrix dstress/dstrain + */ + GEOS_HOST_DEVICE + GEOS_FORCE_INLINE + real64 computeStabilizationScaling( localIndex const k ) const + { + // TODO: generalize this to other constitutive models (currently we assume linear elasticity). + return 2.0 * m_constitutiveUpdate.getShearModulus( k ); + } +}; + +/// The factory used to construct a ExplicitChemoMechanics kernel. +using ExplicitChemoMechanicsFactory = finiteElement::KernelFactory< ExplicitChemoMechanics, + arrayView1d< globalIndex const > const, + globalIndex, + CRSMatrixView< real64, globalIndex const > const, + arrayView1d< real64 > const, + real64 const, + real64 const (&)[3] >; + +} // namespace solidMechanicsLagrangianFEMKernels + +} // namespace geos + +#include "finiteElement/kernelInterface/SparsityKernelBase.hpp" + +#endif // GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_EXPLICITCHEMOMECHANICS_HPP_ diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitChemoMechanics_impl.hpp b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitChemoMechanics_impl.hpp new file mode 100644 index 00000000000..f8a943df746 --- /dev/null +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/ExplicitChemoMechanics_impl.hpp @@ -0,0 +1,234 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ExplicitChemoMechanics_impl.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_EXPLICITCHEMOMECHANICS_IMPL_HPP_ +#define GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_EXPLICITCHEMOMECHANICS_IMPL_HPP_ + +#include "ExplicitChemoMechanics.hpp" +#include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" +#include "physicsSolvers/fluidFlow/SinglePhaseReactiveTransportFields.hpp" +#include "physicsSolvers/multiphysics/PoromechanicsFields.hpp" +#include "physicsSolvers/solidMechanics/SolidMechanicsFields.hpp" + +namespace geos +{ + +namespace solidMechanicsLagrangianFEMKernels +{ + +template< typename SUBREGION_TYPE, + typename CONSTITUTIVE_TYPE, + typename FE_TYPE > + +ExplicitChemoMechanics< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE >:: +ExplicitChemoMechanics( NodeManager const & nodeManager, + EdgeManager const & edgeManager, + FaceManager const & faceManager, + localIndex const targetRegionIndex, + SUBREGION_TYPE const & elementSubRegion, + FE_TYPE const & finiteElementSpace, + CONSTITUTIVE_TYPE & inputConstitutiveType, + arrayView1d< globalIndex const > const inputDofNumber, + globalIndex const rankOffset, + CRSMatrixView< real64, globalIndex const > const inputMatrix, + arrayView1d< real64 > const inputRhs, + real64 const inputDt, + real64 const (&inputGravityVector)[3] ): + Base( nodeManager, + edgeManager, + faceManager, + targetRegionIndex, + elementSubRegion, + finiteElementSpace, + inputConstitutiveType, + inputDofNumber, + rankOffset, + inputMatrix, + inputRhs, + inputDt ), + m_X( nodeManager.referencePosition()), + m_disp( nodeManager.getField< fields::solidMechanics::totalDisplacement >() ), + m_uhat( nodeManager.getField< fields::solidMechanics::incrementalDisplacement >() ), + m_gravityVector{ inputGravityVector[0], inputGravityVector[1], inputGravityVector[2] }, + m_bulkDensity( elementSubRegion.template getField< fields::poromechanics::bulkDensity >() ), + m_pressure( elementSubRegion.template getField< fields::flow::pressure >() ), + m_pressure_n( elementSubRegion.template getField< fields::flow::pressure_n >() ), + m_initialTemperature( elementSubRegion.template getField< fields::flow::initialTemperature >() ), + m_temperature( elementSubRegion.template getField< fields::flow::temperature >() ), + m_temperature_n( elementSubRegion.template getField< fields::flow::temperature_n >() ), + m_mineralReactionMolarIncrements( elementSubRegion.template getField< fields::flow::kineticReactionMolarIncrements >() ) +{} + +template< typename SUBREGION_TYPE, + typename CONSTITUTIVE_TYPE, + typename FE_TYPE > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void ExplicitChemoMechanics< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE >:: +setup( localIndex const k, + StackVariables & stack ) const +{ + m_finiteElementSpace.template setup< FE_TYPE >( k, m_meshData, stack.feStack ); + localIndex const numSupportPoints = + m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + stack.numRows = 3 * numSupportPoints; + stack.numCols = stack.numRows; + + for( localIndex a = 0; a < numSupportPoints; ++a ) + { + localIndex const localNodeIndex = m_elemsToNodes( k, a ); + + for( int i = 0; i < 3; ++i ) + { +#if defined(CALC_FEM_SHAPE_IN_KERNEL) + stack.xLocal[ a ][ i ] = m_X[ localNodeIndex ][ i ]; +#endif + stack.u_local[ a ][i] = m_disp[ localNodeIndex ][i]; + stack.uhat_local[ a ][i] = m_uhat[ localNodeIndex ][i]; + stack.localRowDofIndex[a*3+i] = m_dofNumber[localNodeIndex]+i; + stack.localColDofIndex[a*3+i] = m_dofNumber[localNodeIndex]+i; + } + } + + // Add stabilization to block diagonal parts of the local jacobian + // (this is a no-operation with FEM classes) + real64 const stabilizationScaling = computeStabilizationScaling( k ); + m_finiteElementSpace.template addGradGradStabilizationMatrix + < FE_TYPE, numDofPerTrialSupportPoint, true >( stack.feStack, + stack.localJacobian, + -stabilizationScaling ); +} + +template< typename SUBREGION_TYPE, + typename CONSTITUTIVE_TYPE, + typename FE_TYPE > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +void ExplicitChemoMechanics< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE >:: +quadraturePointKernel( localIndex const k, + localIndex const q, + StackVariables & stack ) const +{ + real64 dNdX[ numNodesPerElem ][ 3 ]; + real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, + stack.feStack, dNdX ); + + real64 strainInc[6] = {0}; + real64 totalStress[6] = {0}; + + typename CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps stiffness; + + FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, strainInc ); + + // Evaluate total stress and its derivatives + // TODO: allow for a customization of the kernel to pass the average pressure to the small strain update (to account for cap pressure + // later) + m_constitutiveUpdate.smallStrainUpdateExplicitChemoMechanics( k, q, + m_dt, + m_pressure[k], + m_pressure_n[k], + m_temperature[k], + m_temperature_n[k], + m_initialTemperature[k], + m_mineralReactionMolarIncrements[k], + strainInc, + totalStress, + stiffness ); + + for( localIndex i=0; i<6; ++i ) + { + totalStress[i] *= -detJxW; + } + + // Here we consider the bodyForce is purely from the solid + // Warning: here, we lag (in iteration) the displacement dependence of bulkDensity + real64 const gravityForce[3] = { m_gravityVector[0] * m_bulkDensity( k, q )* detJxW, + m_gravityVector[1] * m_bulkDensity( k, q )* detJxW, + m_gravityVector[2] * m_bulkDensity( k, q )* detJxW }; + + real64 N[numNodesPerElem]; + FE_TYPE::calcN( q, stack.feStack, N ); + FE_TYPE::plusGradNajAijPlusNaFi( dNdX, + totalStress, + N, + gravityForce, + reinterpret_cast< real64 (&)[numNodesPerElem][3] >(stack.localResidual) ); + real64 const stabilizationScaling = computeStabilizationScaling( k ); + m_finiteElementSpace.template + addEvaluatedGradGradStabilizationVector< FE_TYPE, + numDofPerTrialSupportPoint >( stack.feStack, + stack.uhat_local, + reinterpret_cast< real64 (&)[numNodesPerElem][3] >(stack.localResidual), + -stabilizationScaling ); + stiffness.template upperBTDB< numNodesPerElem >( dNdX, -detJxW, stack.localJacobian ); +} + +template< typename SUBREGION_TYPE, + typename CONSTITUTIVE_TYPE, + typename FE_TYPE > +GEOS_HOST_DEVICE +GEOS_FORCE_INLINE +real64 ExplicitChemoMechanics< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE >:: +complete( localIndex const k, + StackVariables & stack ) const +{ + GEOS_UNUSED_VAR( k ); + real64 maxForce = 0; + + // TODO: Does this work if BTDB is non-symmetric? + CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps::template fillLowerBTDB< numNodesPerElem >( stack.localJacobian ); + localIndex const numSupportPoints = + m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack ); + for( int localNode = 0; localNode < numSupportPoints; ++localNode ) + { + for( int dim = 0; dim < numDofPerTestSupportPoint; ++dim ) + { + localIndex const dof = + LvArray::integerConversion< localIndex >( stack.localRowDofIndex[ numDofPerTestSupportPoint * localNode + dim ] - m_dofRankOffset ); + if( dof < 0 || dof >= m_matrix.numRows() ) + continue; + m_matrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( dof, + stack.localRowDofIndex, + stack.localJacobian[ numDofPerTestSupportPoint * localNode + dim ], + stack.numRows ); + + RAJA::atomicAdd< parallelDeviceAtomic >( &m_rhs[ dof ], stack.localResidual[ numDofPerTestSupportPoint * localNode + dim ] ); + maxForce = fmax( maxForce, fabs( stack.localResidual[ numDofPerTestSupportPoint * localNode + dim ] ) ); + } + } + return maxForce; +} + +template< typename SUBREGION_TYPE, + typename CONSTITUTIVE_TYPE, + typename FE_TYPE > +template< typename POLICY, + typename KERNEL_TYPE > +real64 +ExplicitChemoMechanics< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE >::kernelLaunch( localIndex const numElems, + KERNEL_TYPE const & kernelComponent ) +{ + return Base::template kernelLaunch< POLICY, KERNEL_TYPE >( numElems, kernelComponent ); +} + +} // namespace solidMechanicsLagrangianFEMKernels + +} // namespace geos + +#endif // GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_EXPLICITCHEMOMECHANICS_IMPL_HPP_ diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsExplicitChemoMechanicsKernels.cpp.template b/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsExplicitChemoMechanicsKernels.cpp.template new file mode 100644 index 00000000000..a7fc5514a81 --- /dev/null +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/SolidMechanicsExplicitChemoMechanicsKernels.cpp.template @@ -0,0 +1,38 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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. + * ------------------------------------------------------------------------------------------------------------ + */ + +#include "physicsSolvers/solidMechanics/kernels/ExplicitChemoMechanics_impl.hpp" + +using ExplicitChemoMechanicsPolicy = @ExplicitChemoMechanicsPolicy@; + +#define INSTANTIATION( NAME )\ +template class NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >; \ +template real64 NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ >::kernelLaunch< NAME##Policy, \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > > \ + ( localIndex const, \ + NAME < @SUBREGION_TYPE@, @CONSTITUTIVE_TYPE@, @FE_TYPE@ > const & ); \ + + +namespace geos +{ +using namespace constitutive; +using namespace finiteElement; +namespace solidMechanicsLagrangianFEMKernels +{ + INSTANTIATION( ExplicitChemoMechanics ) +} +} + +#undef INSTANTIATION diff --git a/src/coreComponents/physicsSolvers/solidMechanics/kernels/policies.hpp.in b/src/coreComponents/physicsSolvers/solidMechanics/kernels/policies.hpp.in index c14654cf0c7..bafc3a064b9 100644 --- a/src/coreComponents/physicsSolvers/solidMechanics/kernels/policies.hpp.in +++ b/src/coreComponents/physicsSolvers/solidMechanics/kernels/policies.hpp.in @@ -18,6 +18,7 @@ using ExplicitSmallStrainPolicy = @ExplicitSmallStrainPolicy@; using ExplicitFiniteStrainPolicy = @ExplicitFiniteStrainPolicy@; +using ExplicitChemoMechanicsPolicy = @ExplicitChemoMechanicsPolicy@; using FixedStressThermoPoromechanicsPolicy = @FixedStressThermoPoromechanicsPolicy@; using ImplicitSmallStrainNewmarkPolicy = @ImplicitSmallStrainNewmarkPolicy@; using ImplicitSmallStrainQuasiStaticPolicy = @ImplicitSmallStrainQuasiStaticPolicy@; From 99b56dd99d405e539c0856290176528b075b3e94 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Thu, 30 Oct 2025 19:34:16 -0700 Subject: [PATCH 61/66] updated 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 d8dd4b7de58..2b2aeaf270e 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit d8dd4b7de58cdf9f37f63042fab18ea4777991fb +Subproject commit 2b2aeaf270ef2e1e0a6a9f90f9f18a31aa252bd8 From 67aba0b1783c160a6cd619fb09bf0209f1f4799d Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Sun, 2 Nov 2025 16:44:20 -0800 Subject: [PATCH 62/66] added a sourceFlux kernel to fix cuda issue --- .../physicsSolvers/fluidFlow/CMakeLists.txt | 2 + .../SinglePhaseReactiveTransport.cpp | 216 ++---------- .../SinglePhaseReactiveTransport.hpp | 2 + .../reactive/SourceFluxComputeKernel.hpp | 310 ++++++++++++++++++ .../ThermalSourceFluxComputeKernel.hpp | 213 ++++++++++++ 5 files changed, 559 insertions(+), 184 deletions(-) create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/SourceFluxComputeKernel.hpp create mode 100644 src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt index c406ebe631d..a6d1e9162a4 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt +++ b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt @@ -72,9 +72,11 @@ set( fluidFlowSolvers_headers kernels/singlePhase/reactive/KernelLaunchSelectors.hpp kernels/singlePhase/reactive/ReactionUpdateKernel.hpp kernels/singlePhase/reactive/ResidualNormKernel.hpp + kernels/singlePhase/reactive/SourceFluxComputeKernel.hpp kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp + kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp kernels/compositional/AccumulationKernel.hpp kernels/compositional/AquiferBCKernel.hpp kernels/compositional/PPUPhaseFlux.hpp diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 3097325009e..9ebe4f1c4f7 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -913,18 +913,15 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, MeshLevel & mesh, string_array const & ) { - integer const isThermal = m_isThermal; - integer const numPrimarySpecies = m_numPrimarySpecies; - fsManager.apply< ElementSubRegionBase, SourceFluxBoundaryCondition >( time_n + dt, mesh, SourceFluxBoundaryCondition::catalogName(), - [&, isThermal, numPrimarySpecies]( SourceFluxBoundaryCondition const & fs, - string const & setName, - SortedArrayView< localIndex const > const & targetSet, - ElementSubRegionBase & subRegion, - string const & ) + [&]( SourceFluxBoundaryCondition const & fs, + string const & setName, + SortedArrayView< localIndex const > const & targetSet, + ElementSubRegionBase & subRegion, + string const & ) { if( m_nonlinearSolverParameters.m_numNewtonIterations == 0 ) { @@ -982,192 +979,43 @@ void SinglePhaseReactiveTransport::applySourceFluxBC( real64 const time_n, // get the normalizer real64 const sizeScalingFactor = bcAllSetsSize[bcNameToBcId.at( fs.getName())]; - if( isThermal ) + if( m_isThermal ) { - using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid const & fluid = getConstitutiveModel< reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ) ); - arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); - arrayView4d< real64 const, - reactivefluid::USD_SPECIES_DC > const dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations = - fluid.dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations(); - arrayView2d< real64 const, singlefluid::USD_FLUID > const density = fluid.density(); - arrayView3d< real64 const, constitutive::singlefluid::USD_FLUID_DER > const dDensity = fluid.dDensity(); - arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const enthalpy = fluid.enthalpy(); - arrayView3d< real64 const, constitutive::singlefluid::USD_FLUID_DER > const dEnthalpy = fluid.dEnthalpy(); - - forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, - targetSet, - rankOffset, - ghostRank, - dofNumber, - numPrimarySpecies, - primarySpeciesAggregateConcentration, - dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, - density, - dDensity, - enthalpy, - dEnthalpy, - rhsContributionArrayView, - localRhs, - localMatrix, - massProd] GEOS_HOST_DEVICE ( localIndex const a ) - { - singlePhaseReactiveBaseKernels::internal::kernelLaunchSelectorCompSwitch( numPrimarySpecies, [&] ( auto NS ) - { - integer constexpr NUM_SPECIES = NS(); - - // we need to filter out ghosts here, because targetSet may contain them - localIndex const ei = targetSet[a]; - if( ghostRank[ei] >= 0 ) - { - return; - } - - // add the value to the mass balance equation - globalIndex const massRowIndex = dofNumber[ei] - rankOffset; - globalIndex const energyRowIndex = massRowIndex + 1; - globalIndex const speciesRowBeginIndex = massRowIndex + 2; - real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor - // here! - localRhs[massRowIndex] += rhsValue; - massProd += rhsValue; - - // add the value to the energy balance equation and species mass balance equations if the flux is positive (i.e., it's a - // producer) - if( rhsContributionArrayView[a] > 0.0 ) - { - globalIndex const pressureDofIndex = dofNumber[ei] - rankOffset; - globalIndex const temperatureDofIndex = pressureDofIndex + 1; - - globalIndex dofIndices[2+NUM_SPECIES]{}; - - dofIndices[0] = pressureDofIndex; - dofIndices[1] = temperatureDofIndex; - - for( integer i = 0; i < NUM_SPECIES; ++i ) - { - dofIndices[i+2] = pressureDofIndex + i + 2; - } - - // add the value to the energy balance equation - localRhs[energyRowIndex] += enthalpy[ei][0] * rhsValue; - - real64 jacobianEnergyFlux[2+NUM_SPECIES]{0.0}; - - jacobianEnergyFlux[0] = rhsValue * dEnthalpy[ei][0][DerivOffset::dP]; - jacobianEnergyFlux[1] = rhsValue * dEnthalpy[ei][0][DerivOffset::dT]; - - localMatrix.template addToRow< serialAtomic >( energyRowIndex, - dofIndices, - jacobianEnergyFlux, - 2+NUM_SPECIES ); - - // add the value to the species mass balance equations - for( integer i = 0; i < NUM_SPECIES; ++i ) - { - localRhs[speciesRowBeginIndex + i] += primarySpeciesAggregateConcentration[ei][0][i] / density[ei][0] * rhsValue; - - real64 jacobianSpeciesFlux[2+NUM_SPECIES] = {0.0}; - jacobianSpeciesFlux[0] += -primarySpeciesAggregateConcentration[ei][0][i] * dDensity[ei][0][DerivOffset::dP] / (density[ei][0] * density[ei][0]) * rhsValue; - jacobianSpeciesFlux[1] += -primarySpeciesAggregateConcentration[ei][0][i] * dDensity[ei][0][DerivOffset::dT] / (density[ei][0] * density[ei][0]) * rhsValue; - - for( integer j = 0; j < NUM_SPECIES; ++j ) - { - jacobianSpeciesFlux[j+2] += dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[ei][0][i][j] / density[ei][0] * rhsValue; - } - - localMatrix.template addToRow< serialAtomic >( speciesRowBeginIndex + i, - dofIndices, - jacobianSpeciesFlux, - 2+NUM_SPECIES ); - } - } - } ); - } ); + thermalSinglePhaseReactiveBaseKernels:: + SourceFluxComputeKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, + rankOffset, + dofNumber, + ghostRank, + targetSet, + rhsContributionArrayView, + sizeScalingFactor, + fluid, + localMatrix, + localRhs, + massProd ); } else { - using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; reactivefluid::ReactiveCompressibleSinglePhaseFluid const & fluid = getConstitutiveModel< reactivefluid::ReactiveCompressibleSinglePhaseFluid >( subRegion, subRegion.template getReference< string >( viewKeyStruct::fluidNamesString() ) ); - arrayView3d< real64 const, reactivefluid::USD_SPECIES > const primarySpeciesAggregateConcentration = fluid.primarySpeciesAggregateConcentration(); - arrayView4d< real64 const, - reactivefluid::USD_SPECIES_DC > const dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations = - fluid.dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations(); - arrayView2d< real64 const, singlefluid::USD_FLUID > const density = fluid.density(); - arrayView3d< real64 const, constitutive::singlefluid::USD_FLUID_DER > const dDensity = fluid.dDensity(); - - forAll< parallelDevicePolicy<> >( targetSet.size(), [sizeScalingFactor, - targetSet, - rankOffset, - ghostRank, - dofNumber, - numPrimarySpecies, - primarySpeciesAggregateConcentration, - dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations, - density, - dDensity, - rhsContributionArrayView, - localRhs, - localMatrix, - massProd] GEOS_HOST_DEVICE ( localIndex const a ) - { - singlePhaseReactiveBaseKernels::internal::kernelLaunchSelectorCompSwitch( numPrimarySpecies, [&] ( auto NS ) - { - integer constexpr NUM_SPECIES = NS(); - - // we need to filter out ghosts here, because targetSet may contain them - localIndex const ei = targetSet[a]; - if( ghostRank[ei] >= 0 ) - { - return; - } - - // add the value to the mass balance equation - globalIndex const massRowIndex = dofNumber[ei] - rankOffset; - globalIndex const speciesRowBeginIndex = massRowIndex + 1; - real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor - // here! - localRhs[massRowIndex] += rhsValue; - massProd += rhsValue; - - //add the value to the species mass balance equations if the flux is positive (i.e., it's a producer) - if( rhsContributionArrayView[a] > 0.0 ) - { - globalIndex const pressureDofIndex = dofNumber[ei] - rankOffset; - - globalIndex dofIndices[1+NUM_SPECIES]{}; - - dofIndices[0] = pressureDofIndex; - - for( integer i = 0; i < NUM_SPECIES; ++i ) - { - dofIndices[i+1] = pressureDofIndex + i + 1; - } - - for( integer i = 0; i < NUM_SPECIES; ++i ) - { - localRhs[speciesRowBeginIndex + i] += primarySpeciesAggregateConcentration[ei][0][i] / density[ei][0] * rhsValue; - - real64 jacobian[1+NUM_SPECIES] = {0.0}; - jacobian[0] += -primarySpeciesAggregateConcentration[ei][0][i] * dDensity[ei][0][DerivOffset::dP] / (density[ei][0] * density[ei][0]) * rhsValue; - - for( integer j = 0; j < NUM_SPECIES; ++j ) - { - jacobian[j+1] += dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[ei][0][i][j] / density[ei][0] * rhsValue; - } - - localMatrix.template addToRow< serialAtomic >( speciesRowBeginIndex + i, - dofIndices, - jacobian, - 1+NUM_SPECIES ); - } - } - } ); - } ); + singlePhaseReactiveBaseKernels:: + SourceFluxComputeKernelFactory:: + createAndLaunch< parallelDevicePolicy<> >( m_numPrimarySpecies, + rankOffset, + dofNumber, + ghostRank, + targetSet, + rhsContributionArrayView, + sizeScalingFactor, + fluid, + localMatrix, + localRhs, + massProd ); } SourceFluxStatsAggregator::forAllFluxStatWrappers( subRegion, fs.getName(), diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index 92fad383f29..e8c45a7260a 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -30,9 +30,11 @@ #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/SourceFluxComputeKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp" #include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp" +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp" #include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp" diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/SourceFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/SourceFluxComputeKernel.hpp new file mode 100644 index 00000000000..1ef58f942aa --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/SourceFluxComputeKernel.hpp @@ -0,0 +1,310 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 SourceFluxComputeKernel.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_SOURCEFLUXCOMPUTEKERNELS_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_SOURCEFLUXCOMPUTEKERNELS_HPP + +#include "common/DataTypes.hpp" +#include "common/GEOS_RAJA_Interface.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.hpp" +#include "constitutive/fluid/reactivefluid/ReactiveFluidLayouts.hpp" +#include "constitutive/fluid/singlefluid/SingleFluidBase.hpp" +#include "constitutive/fluid/singlefluid/SingleFluidUtils.hpp" +#include "codingUtilities/Utilities.hpp" + +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/KernelLaunchSelectors.hpp" + +namespace geos +{ + +namespace singlePhaseReactiveBaseKernels +{ + +/******************************** SourceFluxComputeKernel ********************************/ + +/** + * @class SourceFluxComputeKernel + * @brief Define the interface for the assembly kernel in charge of source flux + */ +template< integer NUM_DOF, integer NUM_SPECIES, typename BASE_FLUID_TYPE > +class SourceFluxComputeKernel +{ + +public: + + /// Compute time value for the number of degrees of freedom + static constexpr integer numDof = NUM_DOF; + + /// Compute time value for the number of equations + static constexpr integer numEqn = NUM_DOF; + + /// Compile time value for the number of primary species + static constexpr integer numSpecies = NUM_SPECIES; + + using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; + + SourceFluxComputeKernel( globalIndex const rankOffset, + arrayView1d< globalIndex const > const dofNumber, + arrayView1d< integer const > const elemGhostRank, + arrayView1d< real64 const > const rhsContributionArrayView, + real64 const sizeScalingFactor, + constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE > const & fluid, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs, + RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd ) + : + m_rankOffset( rankOffset ), + m_dofNumber( dofNumber ), + m_elemGhostRank( elemGhostRank ), + m_rhsContributionArrayView( rhsContributionArrayView ), + m_sizeScalingFactor( sizeScalingFactor ), + m_primarySpeciesAggregateConcentration( fluid.primarySpeciesAggregateConcentration() ), + m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations( fluid.dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations() ), + m_density( fluid.density() ), + m_dDensity( fluid.dDensity() ), + m_localMatrix( localMatrix ), + m_localRhs( localRhs ), + m_massProd( massProd ) + {} + + /** + * @struct StackVariables + * @brief Kernel variables (dof numbers, jacobian and residual) located on the stack + */ + struct StackVariables + { +public: + + /// Index of the local row corresponding to this element + localIndex massRowIndex = -1; + + /// Index of the matrix row/column corresponding to the dof in this element + globalIndex dofIndices[numDof]{}; + + /// Storage for the element local residual vector for species rows + real64 localSpeciesRhs[numSpecies]{}; + + /// Storage for the element local Jacobian matrix for species rows + real64 localSpeciesJacobian[numSpecies][numDof]{}; + + real64 totalInflowMass = 0.0; + + }; + + /** + * @brief Getter for the ghost rank of an element + * @param[in] ei the element index + * @return the ghost rank of the element + */ + GEOS_HOST_DEVICE + integer elemGhostRank( localIndex const ei ) const + { return m_elemGhostRank( ei ); } + + /** + * @brief Performs the setup phase for the kernel. + * @param[in] ei the element index + * @param[in] a the target set index + * @param[in] stack the stack variables + */ + GEOS_HOST_DEVICE + void setup( localIndex const ei, + localIndex const a, + StackVariables & stack ) const + { + // set row index and degrees of freedom indices for this element + stack.massRowIndex = m_dofNumber[ei] - m_rankOffset; + for( integer idof = 0; idof < numDof; ++idof ) + { + stack.dofIndices[idof] = m_dofNumber[ei] + idof - m_rankOffset; + } + + stack.totalInflowMass = m_rhsContributionArrayView[a]; + } + + /** + * @brief Compute the local source flux 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 computeSourceFlux( localIndex const ei, + StackVariables & stack ) const + { + real64 const scaledInflowMass = stack.totalInflowMass / m_sizeScalingFactor; + + for( integer i = 0; i < numSpecies; ++i ) + { + stack.localSpeciesRhs[i] += m_primarySpeciesAggregateConcentration[ei][0][i] / m_density[ei][0] * scaledInflowMass; + stack.localSpeciesJacobian[i][0] += -m_primarySpeciesAggregateConcentration[ei][0][i] * m_dDensity[ei][0][DerivOffset::dP] / (m_density[ei][0] * m_density[ei][0]) * scaledInflowMass; + + for( integer j = 0; j < numSpecies; ++j ) + { + stack.localSpeciesJacobian[i][j+numDof-numSpecies] += m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations[ei][0][i][j] / m_density[ei][0] * scaledInflowMass; + } + } + } + + /** + * @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 GEOS_UNUSED_PARAM( ei ), + StackVariables & stack ) const + { + m_massProd += stack.totalInflowMass / m_sizeScalingFactor; + m_localRhs[stack.massRowIndex] += stack.totalInflowMass / m_sizeScalingFactor; + + if( stack.totalInflowMass > 0.0 ) + { + for( integer i = 0; i < numSpecies; ++i ) + { + globalIndex const speciesRowBeginIndex = stack.massRowIndex + numEqn - numSpecies; + m_localRhs[speciesRowBeginIndex + i] += stack.localSpeciesRhs[i]; + + // add contribution to global residual and jacobian (no need for atomics here) + m_localMatrix.template addToRow< serialAtomic >( speciesRowBeginIndex+i, + stack.dofIndices, + stack.localSpeciesJacobian[i], + numDof ); + } + } + } + + /** + * @brief Performs the kernel launch + * @tparam POLICY the policy used in the RAJA kernels + * @tparam KERNEL_TYPE the kernel type + * @param[in] targetSet the target set for source flux + * @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( SortedArrayView< localIndex const > const targetSet, + KERNEL_TYPE const & kernelComponent ) + { + GEOS_MARK_FUNCTION; + + forAll< POLICY >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) + { + // we need to filter out ghosts here, because targetSet may contain them + localIndex const ei = targetSet[a]; + + if( kernelComponent.elemGhostRank( ei ) >= 0 ) + { + return; + } + + typename KERNEL_TYPE::StackVariables stack; + + kernelComponent.setup( ei, a, stack ); + kernelComponent.computeSourceFlux( ei, stack ); + kernelComponent.complete( ei, stack ); + } ); + } + +protected: + + /// Offset for my MPI rank + globalIndex const m_rankOffset; + + /// View on the dof numbers + arrayView1d< globalIndex const > const m_dofNumber; + + /// View on the ghost ranks + arrayView1d< integer const > const m_elemGhostRank; + + /// View on the rhs contribution + arrayView1d< real64 const > const m_rhsContributionArrayView; + /// size scaling factor + real64 const m_sizeScalingFactor; + + // View on the total concentration of ions that contain the primary species + arrayView3d< real64 const, constitutive::reactivefluid::USD_SPECIES > const m_primarySpeciesAggregateConcentration; + // View on the derivatives of total ion concentration for the primary species wrt log of primary species concentration + arrayView4d< real64 const, constitutive::reactivefluid::USD_SPECIES_DC > const m_dPrimarySpeciesAggregateConcentration_dLogPrimarySpeciesConcentrations; + + // View on the fluid density + arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const m_density; + // View on the derivatives of fluid density + arrayView3d< real64 const, constitutive::singlefluid::USD_FLUID_DER > const m_dDensity; + + /// View on the local CRS matrix + CRSMatrixView< real64, globalIndex const > const m_localMatrix; + /// View on the local RHS + arrayView1d< real64 > const m_localRhs; + + RAJA::ReduceSum< parallelDeviceReduce, real64 > m_massProd; + +}; + +/** + * @class SourceFluxComputeKernelFactory + */ +class SourceFluxComputeKernelFactory +{ +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] rankOffset the offset of my MPI rank + * @param[in] dofNumber the degress of freedom numbers + * @param[in] elemGhostRank the array of element ghost rank + * @param[in] targetSet the target set array + * @param[in] rhsContributionArrayView the rhs contribution array + * @param[in] sizeScalingFactor the size scaling factor + * @param[in] fluid the fluid model + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + * @param[inout] massProd the total mass produced + */ + template< typename POLICY, typename BASE_FLUID_TYPE > + static void + createAndLaunch( integer const numSpecies, + globalIndex const rankOffset, + arrayView1d< globalIndex const > const dofNumber, + arrayView1d< integer const > const elemGhostRank, + SortedArrayView< localIndex const > const targetSet, + arrayView1d< real64 const > const rhsContributionArrayView, + real64 const sizeScalingFactor, + constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE > const & fluid, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs, + RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd ) + { + internal::kernelLaunchSelectorCompSwitch( numSpecies, [&] ( auto NS ) + { + integer constexpr NUM_SPECIES = NS(); + integer constexpr NUM_DOF = 1+NS(); + + SourceFluxComputeKernel< NUM_DOF, NUM_SPECIES, BASE_FLUID_TYPE > kernel( rankOffset, dofNumber, elemGhostRank, rhsContributionArrayView, sizeScalingFactor, fluid, localMatrix, localRhs, + massProd ); + SourceFluxComputeKernel< NUM_DOF, NUM_SPECIES, BASE_FLUID_TYPE >::template launch< POLICY >( targetSet, kernel ); + } ); + } +}; +} // namespace singlePhaseReactiveBaseKernels + +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_SOURCEFLUXCOMPUTEKERNELS_HPP diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp new file mode 100644 index 00000000000..5ca2376151e --- /dev/null +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp @@ -0,0 +1,213 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * 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 ThermalSourceFluxComputeKernel.hpp + */ + +#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_THERMALSOURCEFLUXCOMPUTEKERNELS_HPP +#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_THERMALSOURCEFLUXCOMPUTEKERNELS_HPP + +#include "physicsSolvers/fluidFlow/kernels/singlePhase/reactive/SourceFluxComputeKernel.hpp" + +namespace geos +{ + +namespace thermalSinglePhaseReactiveBaseKernels +{ + +/******************************** SourceFluxComputeKernel ********************************/ + +/** + * @class SourceFluxComputeKernel + * @brief Define the interface for the assembly kernel in charge of source flux + */ +template< integer NUM_DOF, integer NUM_SPECIES, typename BASE_FLUID_TYPE > +class SourceFluxComputeKernel : public singlePhaseReactiveBaseKernels::SourceFluxComputeKernel< NUM_DOF, NUM_SPECIES, BASE_FLUID_TYPE > +{ + +public: + + using Base = singlePhaseReactiveBaseKernels::SourceFluxComputeKernel< NUM_DOF, NUM_SPECIES, BASE_FLUID_TYPE >; + using Base::numSpecies; + using Base::numDof; + using Base::numEqn; + using Base::m_sizeScalingFactor; + using Base::m_primarySpeciesAggregateConcentration; + using Base::m_density; + using Base::m_dDensity; + using Base::m_localMatrix; + using Base::m_localRhs; + + using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >; + + SourceFluxComputeKernel( globalIndex const rankOffset, + arrayView1d< globalIndex const > const dofNumber, + arrayView1d< integer const > const elemGhostRank, + arrayView1d< real64 const > const rhsContributionArrayView, + real64 const sizeScalingFactor, + constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE > const & fluid, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs, + RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd ) + : + Base( rankOffset, + dofNumber, + elemGhostRank, + rhsContributionArrayView, + sizeScalingFactor, + fluid, + localMatrix, + localRhs, + massProd ), + m_enthalpy( fluid.enthalpy() ), + m_dEnthalpy( fluid.dEnthalpy() ) + {} + + /** + * @struct StackVariables + * @brief Kernel variables (dof numbers, jacobian and residual) located on the stack + */ + struct StackVariables : Base::StackVariables + { +public: + + GEOS_HOST_DEVICE + StackVariables() + : Base::StackVariables() + {} + + using Base::StackVariables::massRowIndex; + using Base::StackVariables::dofIndices; + using Base::StackVariables::localSpeciesJacobian; + using Base::StackVariables::totalInflowMass; + + /// Storage for the element local residual vector for energy row + real64 localEnergyRhs; + + /// Storage for the element local Jacobian matrix for energy row + real64 localEnergyJacobian[numDof]{}; + + }; + + /** + * @brief Compute the local source flux 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 computeSourceFlux( localIndex const ei, + StackVariables & stack ) const + { + Base::computeSourceFlux( ei, stack ); + + real64 const scaledInflowMass = stack.totalInflowMass / m_sizeScalingFactor; + + stack.localEnergyRhs += m_enthalpy[ei][0] * scaledInflowMass; + stack.localEnergyJacobian[0] = scaledInflowMass * m_dEnthalpy[ei][0][DerivOffset::dP]; + stack.localEnergyJacobian[numDof-numSpecies-1] = scaledInflowMass * m_dEnthalpy[ei][0][DerivOffset::dT]; + + for( integer i = 0; i < numSpecies; ++i ) + { + stack.localSpeciesJacobian[i][numDof-numSpecies-1] += -m_primarySpeciesAggregateConcentration[ei][0][i] * m_dDensity[ei][0][DerivOffset::dT] / (m_density[ei][0] * m_density[ei][0]) * + scaledInflowMass; + } + } + + /** + * @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 + { + Base::complete( ei, stack ); + + if( stack.totalInflowMass > 0.0 ) + { + globalIndex const energyRowIndex = stack.massRowIndex + 1; + m_localRhs[energyRowIndex] += stack.localEnergyRhs; + + m_localMatrix.template addToRow< serialAtomic >( energyRowIndex, + stack.dofIndices, + stack.localEnergyJacobian, + numDof ); + } + } + +protected: + + /// Views on enthalpies + arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const m_enthalpy; + arrayView3d< real64 const, constitutive::singlefluid::USD_FLUID_DER > const m_dEnthalpy; + +}; + +/** + * @class SourceFluxComputeKernelFactory + */ +class SourceFluxComputeKernelFactory +{ +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] rankOffset the offset of my MPI rank + * @param[in] dofNumber the degress of freedom numbers + * @param[in] elemGhostRank the array of element ghost rank + * @param[in] targetSet the target set array + * @param[in] rhsContributionArrayView the rhs contribution array + * @param[in] sizeScalingFactor the size scaling factor + * @param[in] fluid the fluid model + * @param[inout] localMatrix the local CRS matrix + * @param[inout] localRhs the local right-hand side vector + * @param[inout] massProd the total mass produced + */ + template< typename POLICY, typename BASE_FLUID_TYPE > + static void + createAndLaunch( integer const numSpecies, + globalIndex const rankOffset, + arrayView1d< globalIndex const > const dofNumber, + arrayView1d< integer const > const elemGhostRank, + SortedArrayView< localIndex const > const targetSet, + arrayView1d< real64 const > const rhsContributionArrayView, + real64 const sizeScalingFactor, + constitutive::reactivefluid::ReactiveSinglePhaseFluid< BASE_FLUID_TYPE > const & fluid, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs, + RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd ) + { + singlePhaseReactiveBaseKernels:: + internal::kernelLaunchSelectorCompSwitch( numSpecies, [&] ( auto NS ) + { + integer constexpr NUM_SPECIES = NS(); + integer constexpr NUM_DOF = 2+NS(); + + SourceFluxComputeKernel< NUM_DOF, NUM_SPECIES, BASE_FLUID_TYPE > kernel( rankOffset, dofNumber, elemGhostRank, rhsContributionArrayView, sizeScalingFactor, fluid, localMatrix, localRhs, + massProd ); + SourceFluxComputeKernel< NUM_DOF, NUM_SPECIES, BASE_FLUID_TYPE >::template launch< POLICY >( targetSet, kernel ); + } ); + } +}; +} // namespace thermalSinglePhaseReactiveBaseKernels + +} // namespace geos + +#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASEREACTIVE_THERMALSOURCEFLUXCOMPUTEKERNELS_HPP From 4c6f9853bb8e60d61e3456dbeab09d25c26262a5 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Sun, 2 Nov 2025 17:35:09 -0800 Subject: [PATCH 63/66] fixed uninitialized --- .../singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp index 5ca2376151e..5c84854e57a 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp @@ -95,7 +95,7 @@ class SourceFluxComputeKernel : public singlePhaseReactiveBaseKernels::SourceFlu using Base::StackVariables::totalInflowMass; /// Storage for the element local residual vector for energy row - real64 localEnergyRhs; + real64 localEnergyRhs=0.0; /// Storage for the element local Jacobian matrix for energy row real64 localEnergyJacobian[numDof]{}; From 8038422028866f9d76ca82ba61ae29d8bcdaaf40 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Mon, 3 Nov 2025 16:49:07 -0800 Subject: [PATCH 64/66] use the local value in the loop --- .../SinglePhaseReactiveTransport.cpp | 20 +++++++++++++------ .../ThermalSourceFluxComputeKernel.hpp | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 9ebe4f1c4f7..5d543342aaa 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -544,6 +544,8 @@ void SinglePhaseReactiveTransport::updateSpeciesAmount( ElementSubRegionBase & s arrayView1d< real64 const > const volume = subRegion.getElementVolume(); arrayView1d< real64 > const deltaVolume = subRegion.getField< fields::flow::deltaVolume >(); + integer const numPrimarySpecies = m_numPrimarySpecies; + if( m_isThermal ) { reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & fluid = @@ -553,7 +555,7 @@ void SinglePhaseReactiveTransport::updateSpeciesAmount( ElementSubRegionBase & s forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) { - for( integer is = 0; is < m_numPrimarySpecies; ++is ) + for( integer is = 0; is < numPrimarySpecies; ++is ) { primarySpeciesAggregateMole[ei][is] = porosity[ei][0] * ( volume[ei] + deltaVolume[ei] ) * primarySpeciesAggregateConcentration[ei][0][is]; @@ -571,7 +573,7 @@ void SinglePhaseReactiveTransport::updateSpeciesAmount( ElementSubRegionBase & s forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) { - for( integer is = 0; is < m_numPrimarySpecies; ++is ) + for( integer is = 0; is < numPrimarySpecies; ++is ) { primarySpeciesAggregateMole[ei][is] = porosity[ei][0] * ( volume[ei] + deltaVolume[ei] ) * primarySpeciesAggregateConcentration[ei][0][is]; @@ -589,6 +591,8 @@ void SinglePhaseReactiveTransport::updateKineticReactionMolarIncrements( real64 arrayView2d< real64, compflow::USD_COMP > const kineticReactionMolarIncrements = subRegion.getField< fields::flow::kineticReactionMolarIncrements >(); + integer const numKineticReactions = m_numKineticReactions; + if( m_isThermal ) { reactivefluid::ReactiveThermalCompressibleSinglePhaseFluid & fluid = @@ -597,7 +601,7 @@ void SinglePhaseReactiveTransport::updateKineticReactionMolarIncrements( real64 forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) { - for( integer r = 0; r < m_numKineticReactions; ++r ) + for( integer r = 0; r < numKineticReactions; ++r ) { kineticReactionMolarIncrements[ei][r] = dt* kineticReactionRates[ei][0][r]; } @@ -611,7 +615,7 @@ void SinglePhaseReactiveTransport::updateKineticReactionMolarIncrements( real64 forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) { - for( integer r = 0; r < m_numKineticReactions; ++r ) + for( integer r = 0; r < numKineticReactions; ++r ) { kineticReactionMolarIncrements[ei][r] = dt* kineticReactionRates[ei][0][r]; } @@ -728,9 +732,11 @@ void SinglePhaseReactiveTransport::updateSurfaceArea( ElementSubRegionBase & sub } else { + integer const numKineticReactions = m_numKineticReactions; + forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei ) { - for( integer ir = 0; ir < m_numKineticReactions; ++ir ) + for( integer ir = 0; ir < numKineticReactions; ++ir ) { surfaceArea[ei][ir] = initialSurfaceArea[ei][ir]; } @@ -1121,6 +1127,8 @@ void SinglePhaseReactiveTransport::applyDirichletBC( real64 const time_n, subRegion.getReference< array2d< real64, compflow::LAYOUT_COMP > >( fields::flow::logPrimarySpeciesConcentration::key() ); integer const numPrimarySpecies = m_numPrimarySpecies; + integer const isThermal = m_isThermal; + forAll< parallelDevicePolicy<> >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a ) { localIndex const ei = targetSet[a]; @@ -1133,7 +1141,7 @@ void SinglePhaseReactiveTransport::applyDirichletBC( real64 const time_n, localIndex const localRow = dofIndex - rankOffset; real64 rhsValue; - integer const speciesDofBeginIndex = m_isThermal? 2:1; + integer const speciesDofBeginIndex = isThermal? 2:1; // 5.1. For each component, apply target global density value for( integer is = 0; is < numPrimarySpecies; ++is ) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp index 5c84854e57a..5fa7f2c201c 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp @@ -195,7 +195,7 @@ class SourceFluxComputeKernelFactory RAJA::ReduceSum< parallelDeviceReduce, real64 > massProd ) { singlePhaseReactiveBaseKernels:: - internal::kernelLaunchSelectorCompSwitch( numSpecies, [&] ( auto NS ) + internal::kernelLaunchSelectorCompSwitch( numSpecies, [&] ( auto NS ) { integer constexpr NUM_SPECIES = NS(); integer constexpr NUM_DOF = 2+NS(); From d92fb91ab4541bd8157da4797c5e0017fb9bc7e5 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Tue, 25 Nov 2025 16:23:51 -0800 Subject: [PATCH 65/66] added ultramafic example --- .../ChemoMechanicsUltramaficSystem_base.xml | 128 ++++++++++++++++ ...anicsUltramaficSystem_initialAggregate.xml | 79 ++++++++++ ...icsUltramaficSystem_initialPrimaryConc.xml | 79 ++++++++++ ...ChemoMechanicsUltramaficSystem_logConc.xml | 38 +++++ ...oMechanicsUltramaficSystem_surfaceArea.xml | 143 ++++++++++++++++++ ...hemoMechanicsUltramaficSystem_wellbore.xml | 115 ++++++++++++++ .../mixedReactionUltramaficSystem_base.xml | 89 +++++++++++ ...ctionUltramaficSystem_initialAggregate.xml | 79 ++++++++++ ...ionUltramaficSystem_initialPrimaryConc.xml | 79 ++++++++++ .../mixedReactionUltramaficSystem_logConc.xml | 38 +++++ ...edReactionUltramaficSystem_surfaceArea.xml | 98 ++++++++++++ ...mixedReactionUltramaficSystem_wellbore.xml | 94 ++++++++++++ src/coreComponents/constitutive/HPCReact | 2 +- .../ReactiveSinglePhaseFluid.cpp | 2 +- 14 files changed, 1061 insertions(+), 2 deletions(-) create mode 100644 inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_base.xml create mode 100644 inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_initialAggregate.xml create mode 100644 inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_initialPrimaryConc.xml create mode 100644 inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_logConc.xml create mode 100644 inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_surfaceArea.xml create mode 100644 inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_wellbore.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_base.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_initialAggregate.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_initialPrimaryConc.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_logConc.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_surfaceArea.xml create mode 100644 inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_wellbore.xml diff --git a/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_base.xml b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_base.xml new file mode 100644 index 00000000000..f9b627f351e --- /dev/null +++ b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_base.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_initialAggregate.xml b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_initialAggregate.xml new file mode 100644 index 00000000000..06056cba380 --- /dev/null +++ b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_initialAggregate.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_initialPrimaryConc.xml b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_initialPrimaryConc.xml new file mode 100644 index 00000000000..906b0b38dbe --- /dev/null +++ b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_initialPrimaryConc.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_logConc.xml b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_logConc.xml new file mode 100644 index 00000000000..8aefe228ee1 --- /dev/null +++ b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_logConc.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + diff --git a/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_surfaceArea.xml b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_surfaceArea.xml new file mode 100644 index 00000000000..fec7e98cc64 --- /dev/null +++ b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_surfaceArea.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_wellbore.xml b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_wellbore.xml new file mode 100644 index 00000000000..3f64cc9d7d0 --- /dev/null +++ b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_wellbore.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_base.xml b/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_base.xml new file mode 100644 index 00000000000..41f69bbd504 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_base.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_initialAggregate.xml b/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_initialAggregate.xml new file mode 100644 index 00000000000..06056cba380 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_initialAggregate.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_initialPrimaryConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_initialPrimaryConc.xml new file mode 100644 index 00000000000..906b0b38dbe --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_initialPrimaryConc.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_logConc.xml b/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_logConc.xml new file mode 100644 index 00000000000..8aefe228ee1 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_logConc.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_surfaceArea.xml b/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_surfaceArea.xml new file mode 100644 index 00000000000..589eec19a67 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_surfaceArea.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_wellbore.xml b/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_wellbore.xml new file mode 100644 index 00000000000..77f4961de58 --- /dev/null +++ b/inputFiles/singlePhaseFlow/reactiveTransport/2DUltramaficSystem/mixedReactionUltramaficSystem_wellbore.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/coreComponents/constitutive/HPCReact b/src/coreComponents/constitutive/HPCReact index 2b2aeaf270e..4cd8dff854c 160000 --- a/src/coreComponents/constitutive/HPCReact +++ b/src/coreComponents/constitutive/HPCReact @@ -1 +1 @@ -Subproject commit 2b2aeaf270ef2e1e0a6a9f90f9f18a31aa252bd8 +Subproject commit 4cd8dff854c6691a1fe885227350ce09cdacaea0 diff --git a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp index 69b7b750934..551ad59bd89 100644 --- a/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp +++ b/src/coreComponents/constitutive/fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp @@ -81,7 +81,7 @@ void ReactiveSinglePhaseFluid< BASE >::postInputInitialization() switch( m_chemicalSystemType ) { case ChemicalSystemType::ultramafic: - m_numPrimarySpecies = 9; + m_numPrimarySpecies = 4; m_numSecondarySpecies = 16; m_numKineticReactions = 5; break; From e9eb09297f36f96617fba791992a71e1e748b2f8 Mon Sep 17 00:00:00 2001 From: Fan Fei Date: Tue, 25 Nov 2025 17:20:07 -0800 Subject: [PATCH 66/66] fixed compile issue and a bug in xml --- ...oMechanicsUltramaficSystem_surfaceArea.xml | 45 ------------------- .../SinglePhaseReactiveTransport.cpp | 7 +++ .../SinglePhaseReactiveTransport.hpp | 1 + 3 files changed, 8 insertions(+), 45 deletions(-) diff --git a/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_surfaceArea.xml b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_surfaceArea.xml index fec7e98cc64..f21fafeb092 100644 --- a/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_surfaceArea.xml +++ b/inputFiles/chemoMechanics/ChemoMechanicsUltramaficSystem_surfaceArea.xml @@ -94,50 +94,5 @@ component="4" scale="4.3e7"/> - - - - - - - - - - diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp index 656224de504..f1a69d02442 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.cpp @@ -682,6 +682,13 @@ void SinglePhaseReactiveTransport::updatePorosityAndPermeability( CellElementSub } } +void SinglePhaseReactiveTransport::updatePorosityAndPermeability( SurfaceElementSubRegion & subRegion ) const +{ + GEOS_MARK_FUNCTION; + + FlowSolverBase::updatePorosityAndPermeability( subRegion ); +} + void SinglePhaseReactiveTransport::updateMixedReactionSystem( ElementSubRegionBase & subRegion ) const { GEOS_MARK_FUNCTION; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp index e8c45a7260a..e4f88ad98fb 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/SinglePhaseReactiveTransport.hpp @@ -158,6 +158,7 @@ class SinglePhaseReactiveTransport : public SinglePhaseBase virtual void updateFluidModel( ObjectManagerBase & dataGroup ) const override; virtual void updatePorosityAndPermeability( CellElementSubRegion & subRegion ) const override; + virtual void updatePorosityAndPermeability( SurfaceElementSubRegion & subRegion ) const override; virtual void initializePostInitialConditionsPreSubGroups() override;