20 #ifndef GEOS_PHYSICSSOLVERS_MULTIPHYSICS_POROMECHANICSKERNELS_THERMALMULTIPHASEPOROMECHANICS_IMPL_HPP_
21 #define GEOS_PHYSICSSOLVERS_MULTIPHYSICS_POROMECHANICSKERNELS_THERMALMULTIPHASEPOROMECHANICS_IMPL_HPP_
23 #include "constitutive/fluid/multifluid/MultiFluidBase.hpp"
32 namespace thermalPoromechanicsKernels
35 template<
typename SUBREGION_TYPE,
36 typename CONSTITUTIVE_TYPE,
43 SUBREGION_TYPE
const & elementSubRegion,
44 FE_TYPE
const & finiteElementSpace,
45 CONSTITUTIVE_TYPE & inputConstitutiveType,
51 real64 const (&gravityVector)[3],
52 string const inputFlowDofKey,
55 integer const useTotalMassEquation,
56 integer const performStressInitialization,
57 string const fluidModelKey ):
64 inputConstitutiveType,
76 performStressInitialization,
78 m_rockInternalEnergy_n( inputConstitutiveType.getInternalEnergy_n() ),
79 m_rockInternalEnergy( inputConstitutiveType.getInternalEnergy() ),
80 m_dRockInternalEnergy_dTemperature( inputConstitutiveType.getDinternalEnergy_dTemperature() ),
81 m_referenceTemperature( elementSubRegion.template getField< fields::flow::initialTemperature >() ),
82 m_temperature_n( elementSubRegion.template getField< fields::flow::temperature_n >() ),
83 m_temperature( elementSubRegion.template getField< fields::flow::temperature >() )
87 string const & fluidModelName = elementSubRegion.template getReference< string >( fluidModelKey );
88 constitutive::MultiFluidBase
const & fluid =
89 elementSubRegion.template getConstitutiveModel< constitutive::MultiFluidBase >( fluidModelName );
92 m_fluidPhaseInternalEnergy = fluid.phaseInternalEnergy();
93 m_dFluidPhaseInternalEnergy = fluid.dPhaseInternalEnergy();
98 template<
typename SUBREGION_TYPE,
99 typename CONSTITUTIVE_TYPE,
108 Base::setup( k, stack );
116 template<
typename SUBREGION_TYPE,
117 typename CONSTITUTIVE_TYPE,
128 real64 dPorosity_dVolStrain = 0.0;
129 real64 dPorosity_dPressure = 0.0;
130 real64 dPorosity_dTemperature = 0.0;
131 real64 dSolidDensity_dPressure = 0.0;
134 m_constitutiveUpdate.smallStrainUpdatePoromechanics( k, q,
145 m_performStressInitialization,
148 dPorosity_dVolStrain,
150 dPorosity_dTemperature,
151 dSolidDensity_dPressure );
154 computeBodyForce( k, q,
156 dPorosity_dVolStrain,
158 dPorosity_dTemperature,
159 dSolidDensity_dPressure,
163 computeFluidIncrement( k, q,
166 dPorosity_dVolStrain,
168 dPorosity_dTemperature,
172 computePoreVolumeConstraint( k,
178 template<
typename SUBREGION_TYPE,
179 typename CONSTITUTIVE_TYPE,
187 real64 const & dPorosity_dVolStrain,
188 real64 const & dPorosity_dPressure,
189 real64 const & dPorosity_dTemperature,
190 real64 const & dSolidDensity_dPressure,
193 Base::computeBodyForce( k, q,
195 dPorosity_dVolStrain,
197 dPorosity_dTemperature,
198 dSolidDensity_dPressure,
199 stack, [&](
real64 const & totalMassDensity,
200 real64 const & mixtureDensity )
206 real64 const dMixtureDens_dTemperature = dPorosity_dTemperature * ( -m_solidDensity( k, q ) + totalMassDensity );
210 LvArray::tensorOps::scaledCopy< 3 >( stack.
dBodyForce_dTemperature, m_gravityVector, dMixtureDens_dTemperature );
215 template<
typename SUBREGION_TYPE,
216 typename CONSTITUTIVE_TYPE,
224 real64 const & porosity_n,
225 real64 const & dPorosity_dVolStrain,
226 real64 const & dPorosity_dPressure,
227 real64 const & dPorosity_dTemperature,
230 using Deriv = constitutive::multifluid::DerivativeOffset;
239 Base::computeFluidIncrement( k, q,
242 dPorosity_dVolStrain,
244 dPorosity_dTemperature,
245 stack, [&](
real64 const & ip,
246 real64 const & phaseAmount,
247 real64 const & phaseAmount_n,
248 real64 const & dPhaseAmount_dVolStrain,
249 real64 const & dPhaseAmount_dP,
250 real64 const (&dPhaseAmount_dC)[maxNumComponents] )
258 real64 dPhaseInternalEnergy_dC[maxNumComponents]{};
261 arraySlice1d<
real64 const, constitutive::multifluid::USD_PHASE - 2 >
const phaseInternalEnergy_n = m_fluidPhaseInternalEnergy_n[k][q];
262 arraySlice1d<
real64 const, constitutive::multifluid::USD_PHASE - 2 >
const phaseInternalEnergy = m_fluidPhaseInternalEnergy[k][q];
263 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_DC - 2 >
const dPhaseInternalEnergy = m_dFluidPhaseInternalEnergy[k][q];
264 arraySlice1d<
real64 const, constitutive::multifluid::USD_PHASE - 2 >
const phaseDensity = m_fluidPhaseDensity[k][q];
265 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_DC - 2 >
const dPhaseDensity = m_dFluidPhaseDensity[k][q];
266 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_COMP - 2 >
const phaseCompFrac = m_fluidPhaseCompFrac[k][q];
267 arraySlice3d<
real64 const, constitutive::multifluid::USD_PHASE_COMP_DC -2 >
const dPhaseCompFrac = m_dFluidPhaseCompFrac[k][q];
268 arraySlice1d<
real64 const, compflow::USD_PHASE - 1 >
const phaseVolFrac = m_fluidPhaseVolFrac[k];
269 arraySlice2d<
real64 const, compflow::USD_PHASE_DC - 1 >
const dPhaseVolFrac = m_dFluidPhaseVolFrac[k];
270 arraySlice2d<
real64 const, compflow::USD_COMP_DC - 1 >
const dGlobalCompFrac_dGlobalCompDensity = m_dGlobalCompFraction_dGlobalCompDensity[k];
274 real64 const dPhaseAmount_dT = dPorosity_dTemperature * phaseVolFrac( ip ) * phaseDensity( ip )
275 + porosity * ( dPhaseVolFrac( ip, Deriv::dT ) * phaseDensity( ip ) + phaseVolFrac( ip ) * dPhaseDensity( ip, Deriv::dT ) );
277 for(
integer ic = 0; ic < m_numComponents; ++ic )
280 + phaseAmount * dPhaseCompFrac( ip, ic, Deriv::dT );
286 stack.
energyIncrement += phaseAmount * phaseInternalEnergy( ip ) - phaseAmount_n * phaseInternalEnergy_n( ip );
291 + phaseAmount * dPhaseInternalEnergy( ip, Deriv::dP );
293 + phaseAmount * dPhaseInternalEnergy( ip, Deriv::dT );
296 applyChainRule( m_numComponents, dGlobalCompFrac_dGlobalCompDensity, dPhaseInternalEnergy[ip], dPhaseInternalEnergy_dC, Deriv::dC );
297 for(
integer jc = 0; jc < m_numComponents; ++jc )
300 + phaseAmount * dPhaseInternalEnergy_dC[jc];
305 real64 const oneMinusPoro = 1 - porosity;
308 stack.
energyIncrement += oneMinusPoro * m_rockInternalEnergy( k, 0 ) - ( 1 - porosity_n ) * m_rockInternalEnergy_n( k, 0 );
311 stack.
dEnergyIncrement_dTemperature += -dPorosity_dTemperature * m_rockInternalEnergy( k, 0 ) + oneMinusPoro * m_dRockInternalEnergy_dTemperature( k, 0 );
314 template<
typename SUBREGION_TYPE,
315 typename CONSTITUTIVE_TYPE,
321 real64 const & porosity_n,
324 using Deriv = constitutive::multifluid::DerivativeOffset;
326 Base::computePoreVolumeConstraint( k,
330 arraySlice2d<
real64 const, compflow::USD_PHASE_DC - 1 >
const dPhaseVolFrac = m_dFluidPhaseVolFrac[k];
333 for(
integer ip = 0; ip < m_numPhases; ++ip )
339 template<
typename SUBREGION_TYPE,
340 typename CONSTITUTIVE_TYPE,
346 real64 const ( &dNdX )[numNodesPerElem][3],
350 using namespace PDEUtilities;
352 Base::assembleMomentumBalanceTerms( N, dNdX, detJxW, stack );
354 constexpr FunctionSpace displacementTrialSpace = FE_TYPE::template getFunctionSpace< numDofPerTrialSupportPoint >();
355 constexpr FunctionSpace displacementTestSpace = displacementTrialSpace;
356 constexpr FunctionSpace pressureTrialSpace = FunctionSpace::P0;
360 BilinearFormUtilities::compute< displacementTestSpace,
362 DifferentialOperator::SymmetricGradient,
363 DifferentialOperator::Identity >
371 BilinearFormUtilities::compute< displacementTestSpace,
373 DifferentialOperator::Identity,
374 DifferentialOperator::Identity >
383 template<
typename SUBREGION_TYPE,
384 typename CONSTITUTIVE_TYPE,
393 using namespace PDEUtilities;
395 Base::assembleElementBasedFlowTerms( dNdX, detJxW, stack );
397 constexpr FunctionSpace displacementTrialSpace = FE_TYPE::template getFunctionSpace< numDofPerTrialSupportPoint >();
398 constexpr FunctionSpace pressureTrialSpace = FunctionSpace::P0;
399 constexpr FunctionSpace pressureTestSpace = pressureTrialSpace;
403 BilinearFormUtilities::compute< pressureTestSpace,
405 DifferentialOperator::Identity,
406 DifferentialOperator::Identity >
416 BilinearFormUtilities::compute< pressureTestSpace,
418 DifferentialOperator::Identity,
419 DifferentialOperator::Identity >
429 LinearFormUtilities::compute< pressureTestSpace,
430 DifferentialOperator::Identity >
437 BilinearFormUtilities::compute< pressureTestSpace,
438 displacementTrialSpace,
439 DifferentialOperator::Identity,
440 DifferentialOperator::Divergence >
448 BilinearFormUtilities::compute< pressureTestSpace,
450 DifferentialOperator::Identity,
451 DifferentialOperator::Identity >
459 BilinearFormUtilities::compute< pressureTestSpace,
461 DifferentialOperator::Identity,
462 DifferentialOperator::Identity >
470 BilinearFormUtilities::compute< pressureTestSpace,
472 DifferentialOperator::Identity,
473 DifferentialOperator::Identity >
483 template<
typename SUBREGION_TYPE,
484 typename CONSTITUTIVE_TYPE,
495 real64 N[numNodesPerElem]{};
496 real64 dNdX[numNodesPerElem][3]{};
497 FE_TYPE::calcN( q, stack.feStack, N );
498 real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal,
499 stack.feStack, dNdX );
502 LvArray::tensorOps::fill< 6 >( stack.strainIncrement, 0.0 );
503 FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement );
508 smallStrainUpdate( k, q, stack );
512 assembleMomentumBalanceTerms( N, dNdX, detJxW, stack );
516 assembleElementBasedFlowTerms( dNdX, detJxW, stack );
519 template<
typename SUBREGION_TYPE,
520 typename CONSTITUTIVE_TYPE,
528 using namespace compositionalMultiphaseUtilities;
530 real64 const maxForce = Base::complete( k, stack );
533 m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack );
534 integer numDisplacementDofs = numSupportPoints * numDofPerTestSupportPoint;
536 if( m_useTotalMassEquation > 0 )
539 real64 work[maxNumComponents + 1]{};
545 for(
int localNode = 0; localNode < numSupportPoints; ++localNode )
547 for(
integer dim = 0; dim < numDofPerTestSupportPoint; ++dim )
549 localIndex const dof = LvArray::integerConversion< localIndex >( stack.localRowDofIndex[numDofPerTestSupportPoint*localNode + dim] - m_dofRankOffset );
552 if( dof < 0 || dof >= m_matrix.numRows() )
557 m_matrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( dof,
567 if( 0 <= massDof && massDof < m_matrix.numRows() )
572 for(
localIndex i = 0; i < m_numComponents; ++i )
574 m_matrix.template addToRow< serialAtomic >( massDof + i,
582 m_matrix.template addToRow< serialAtomic >( massDof + m_numComponents,
593 if( 0 <= energyDof && energyDof < m_matrix.numRows() )
595 m_matrix.template addToRowBinarySearchUnsorted< serialAtomic >( energyDof,
596 stack.localRowDofIndex,
598 numDisplacementDofs );
599 m_matrix.template addToRow< serialAtomic >( energyDof,
603 m_matrix.template addToRow< serialAtomic >( energyDof,
607 m_matrix.template addToRow< serialAtomic >( energyDof,
608 stack.localComponentDofIndices,
618 template<
typename SUBREGION_TYPE,
619 typename CONSTITUTIVE_TYPE,
621 template<
typename POLICY,
622 typename KERNEL_TYPE >
625 KERNEL_TYPE
const & kernelComponent )
630 RAJA::ReduceMax< ReducePolicy< POLICY >,
real64 > maxResidual( 0 );
632 forAll< POLICY >( numElems,
635 typename KERNEL_TYPE::StackVariables stack;
637 kernelComponent.setup( k, stack );
638 for(
integer q=0; q<KERNEL_TYPE::numQuadraturePointsPerElem; ++q )
640 kernelComponent.quadraturePointKernel( k, q, stack );
642 maxResidual.max( kernelComponent.complete( k, stack ) );
644 return maxResidual.get();
#define GEOS_HOST_DEVICE
Marks a host-device function.
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
#define GEOS_FORCE_INLINE
Marks a function or lambda for inlining.
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
This class provides an interface to ObjectManagerBase in order to manage edge data.
The FaceManager class provides an interface to ObjectManagerBase in order to manage face data.
The NodeManager class provides an interface to ObjectManagerBase in order to manage node data.
Defines the kernel structure for solving quasi-static poromechanics.
Implements kernels for solving quasi-static thermal multiphase poromechanics.
GEOS_HOST_DEVICE void computeBodyForce(localIndex const k, localIndex const q, real64 const &porosity, real64 const &dPorosity_dVolStrain, real64 const &dPorosity_dPressure, real64 const &dPorosity_dTemperature, real64 const &dSolidDensity_dPressure, StackVariables &stack) const
Helper function to compute the body force term (\rho g) and its derivatives wrt primary variables.
GEOS_HOST_DEVICE real64 complete(localIndex const k, StackVariables &stack) const
Performs the complete phase for the kernel.
GEOS_HOST_DEVICE void setup(localIndex const k, StackVariables &stack) const
Copy global values from primary field to a local stack array.
GEOS_HOST_DEVICE void computeFluidIncrement(localIndex const k, localIndex const q, real64 const &porosity, real64 const &porosity_n, real64 const &dPorosity_dVolStrain, real64 const &dPorosity_dPressure, real64 const &dPorosity_dTemperature, StackVariables &stack) const
Helper function to compute the fluid mass increment and its derivatives wrt primary variables.
ThermalMultiphasePoromechanics(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 inputDispDofNumber, globalIndex const rankOffset, CRSMatrixView< real64, globalIndex const > const inputMatrix, arrayView1d< real64 > const inputRhs, real64 const inputDt, real64 const (&gravityVector)[3], string const inputFlowDofKey, localIndex const numComponents, localIndex const numPhases, integer const useTotalMassEquation, integer const performStressInitialization, string const fluidModelKey)
Constructor.
static real64 kernelLaunch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Kernel Launcher.
GEOS_HOST_DEVICE void assembleMomentumBalanceTerms(real64 const (&N)[numNodesPerElem], real64 const (&dNdX)[numNodesPerElem][3], real64 const &detJxW, StackVariables &stack) const
Assemble the local linear momentum balance residual and derivatives using total stress and body force...
GEOS_HOST_DEVICE void smallStrainUpdate(localIndex const k, localIndex const q, StackVariables &stack) const
Helper function to compute 1) the total stress, 2) the body force term, and 3) the fluidMass/EnergyIn...
GEOS_HOST_DEVICE void computePoreVolumeConstraint(localIndex const k, real64 const &porosity_n, StackVariables &stack) const
Helper function to compute the pore-volume constraint and its derivatives wrt primary variables.
GEOS_HOST_DEVICE void assembleElementBasedFlowTerms(real64 const (&dNdX)[numNodesPerElem][3], real64 const &detJxW, StackVariables &stack) const
Assemble the local mass/energy balance residual and derivatives using fluid mass/energy increment.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > m_fluidPhaseInternalEnergy_n
Views on phase internal energy.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
LvArray::CRSMatrixView< T, COL_INDEX, localIndex const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
ArraySlice< T, 2, USD > arraySlice2d
Alias for 2D array slice.
ArraySlice< T, 3, USD > arraySlice3d
Alias for 3D array slice.
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
std::int32_t integer
Signed integer type.
Kernel variables (dof numbers, jacobian and residual) located on the stack.
globalIndex localPressureDofIndex
C-array storage for the element local row degrees of freedom.
real64 dTotalStress_dTemperature[6]
Derivative of total stress wrt temperature.
CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps stiffness
Derivative of total stress wrt displacement.
real64 strainIncrement[6]
Strain increment.
real64 temperature
Temperature.
real64 dTotalStress_dPressure[6]
Derivative of total stress wrt pressure.
real64 deltaTemperature
Delta temperature from reference state.
real64 deltaTemperatureFromLastStep
Delta temperature since last time step.
real64 totalStress[6]
Total stress.
Kernel variables allocated on the stack.
real64 dEnergyIncrement_dComponents[maxNumComponents]
Derivative of energy increment wrt global comp fraction.
real64 dEnergyIncrement_dTemperature
Derivative of energy increment wrt temperature.
real64 dLocalResidualEnergy_dTemperature[1][1]
Derivative of energy balance residual wrt temperature.
real64 localResidualEnergy[1]
Energy balance residual.
real64 dEnergyIncrement_dVolStrainIncrement
Derivative of energy increment wrt volumetric strain increment.
real64 dLocalResidualMomentum_dTemperature[Base::StackVariables::numDispDofPerElem][1]
Derivative of linear momentum balance residual wrt temperature.
real64 dPoreVolConstraint_dTemperature
Derivative of pore volume constraint wrt temperature.
real64 energyIncrement
Energy increment.
real64 dLocalResidualEnergy_dComponents[1][maxNumComponents]
Derivative of energy balance residual wrt global comp fraction.
real64 dLocalResidualEnergy_dPressure[1][1]
Derivative of energy balance residual wrt pressure.
globalIndex localTemperatureDofIndex
Local degrees of freedom index of temperature.
real64 dLocalResidualPoreVolConstraint_dTemperature[1][1]
Derivative of pore volume constraint residual wrt pressure.
real64 dBodyForce_dTemperature[3]
Derivative of body force wrt temperature.
real64 dLocalResidualMass_dTemperature[maxNumComponents][1]
Derivative of mass balance residual wrt pressure.
real64 dEnergyIncrement_dPressure
Derivative of energy increment wrt pressure.
real64 dCompMassIncrement_dTemperature[maxNumComponents]
Derivative of mass increment wrt temperature.
real64 dLocalResidualEnergy_dDisplacement[1][Base::StackVariables::numDispDofPerElem]
Derivative of energy balance residual wrt displacement.