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_temperature_n( elementSubRegion.template getField< fields::flow::temperature_n >() ),
82 m_temperature( elementSubRegion.template getField< fields::flow::temperature >() )
86 string const fluidModelName = elementSubRegion.template getReference< string >( fluidModelKey );
87 constitutive::MultiFluidBase
const & fluid =
88 elementSubRegion.template getConstitutiveModel< constitutive::MultiFluidBase >( fluidModelName );
91 m_fluidPhaseInternalEnergy = fluid.phaseInternalEnergy();
92 m_dFluidPhaseInternalEnergy = fluid.dPhaseInternalEnergy();
97 template<
typename SUBREGION_TYPE,
98 typename CONSTITUTIVE_TYPE,
107 Base::setup( k, stack );
114 template<
typename SUBREGION_TYPE,
115 typename CONSTITUTIVE_TYPE,
126 real64 dPorosity_dVolStrain = 0.0;
127 real64 dPorosity_dPressure = 0.0;
128 real64 dPorosity_dTemperature = 0.0;
129 real64 dSolidDensity_dPressure = 0.0;
132 m_constitutiveUpdate.smallStrainUpdatePoromechanics( k, q,
143 m_performStressInitialization,
146 dPorosity_dVolStrain,
148 dPorosity_dTemperature,
149 dSolidDensity_dPressure );
152 computeBodyForce( k, q,
154 dPorosity_dVolStrain,
156 dPorosity_dTemperature,
157 dSolidDensity_dPressure,
161 computeFluidIncrement( k, q,
164 dPorosity_dVolStrain,
166 dPorosity_dTemperature,
170 computePoreVolumeConstraint( k,
176 template<
typename SUBREGION_TYPE,
177 typename CONSTITUTIVE_TYPE,
185 real64 const & dPorosity_dVolStrain,
186 real64 const & dPorosity_dPressure,
187 real64 const & dPorosity_dTemperature,
188 real64 const & dSolidDensity_dPressure,
191 Base::computeBodyForce( k, q,
193 dPorosity_dVolStrain,
195 dPorosity_dTemperature,
196 dSolidDensity_dPressure,
197 stack, [&](
real64 const & totalMassDensity,
198 real64 const & mixtureDensity )
204 real64 const dMixtureDens_dTemperature = dPorosity_dTemperature * ( -m_solidDensity( k, q ) + totalMassDensity );
208 LvArray::tensorOps::scaledCopy< 3 >( stack.
dBodyForce_dTemperature, m_gravityVector, dMixtureDens_dTemperature );
213 template<
typename SUBREGION_TYPE,
214 typename CONSTITUTIVE_TYPE,
222 real64 const & porosity_n,
223 real64 const & dPorosity_dVolStrain,
224 real64 const & dPorosity_dPressure,
225 real64 const & dPorosity_dTemperature,
228 using Deriv = constitutive::multifluid::DerivativeOffset;
237 Base::computeFluidIncrement( k, q,
240 dPorosity_dVolStrain,
242 dPorosity_dTemperature,
243 stack, [&](
real64 const & ip,
244 real64 const & phaseAmount,
245 real64 const & phaseAmount_n,
246 real64 const & dPhaseAmount_dVolStrain,
247 real64 const & dPhaseAmount_dP,
248 real64 const (&dPhaseAmount_dC)[maxNumComponents] )
256 real64 dPhaseInternalEnergy_dC[maxNumComponents]{};
259 arraySlice1d<
real64 const, constitutive::multifluid::USD_PHASE - 2 >
const phaseInternalEnergy_n = m_fluidPhaseInternalEnergy_n[k][q];
260 arraySlice1d<
real64 const, constitutive::multifluid::USD_PHASE - 2 >
const phaseInternalEnergy = m_fluidPhaseInternalEnergy[k][q];
261 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_DC - 2 >
const dPhaseInternalEnergy = m_dFluidPhaseInternalEnergy[k][q];
262 arraySlice1d<
real64 const, constitutive::multifluid::USD_PHASE - 2 >
const phaseDensity = m_fluidPhaseDensity[k][q];
263 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_DC - 2 >
const dPhaseDensity = m_dFluidPhaseDensity[k][q];
264 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_COMP - 2 >
const phaseCompFrac = m_fluidPhaseCompFrac[k][q];
265 arraySlice3d<
real64 const, constitutive::multifluid::USD_PHASE_COMP_DC -2 >
const dPhaseCompFrac = m_dFluidPhaseCompFrac[k][q];
266 arraySlice1d<
real64 const, compflow::USD_PHASE - 1 >
const phaseVolFrac = m_fluidPhaseVolFrac[k];
267 arraySlice2d<
real64 const, compflow::USD_PHASE_DC - 1 >
const dPhaseVolFrac = m_dFluidPhaseVolFrac[k];
268 arraySlice2d<
real64 const, compflow::USD_COMP_DC - 1 >
const dGlobalCompFrac_dGlobalCompDensity = m_dGlobalCompFraction_dGlobalCompDensity[k];
272 real64 const dPhaseAmount_dT = dPorosity_dTemperature * phaseVolFrac( ip ) * phaseDensity( ip )
273 + porosity * ( dPhaseVolFrac( ip, Deriv::dT ) * phaseDensity( ip ) + phaseVolFrac( ip ) * dPhaseDensity( ip, Deriv::dT ) );
275 for(
integer ic = 0; ic < m_numComponents; ++ic )
278 + phaseAmount * dPhaseCompFrac( ip, ic, Deriv::dT );
284 stack.
energyIncrement += phaseAmount * phaseInternalEnergy( ip ) - phaseAmount_n * phaseInternalEnergy_n( ip );
289 + phaseAmount * dPhaseInternalEnergy( ip, Deriv::dP );
291 + phaseAmount * dPhaseInternalEnergy( ip, Deriv::dT );
294 applyChainRule( m_numComponents, dGlobalCompFrac_dGlobalCompDensity, dPhaseInternalEnergy[ip], dPhaseInternalEnergy_dC, Deriv::dC );
295 for(
integer jc = 0; jc < m_numComponents; ++jc )
298 + phaseAmount * dPhaseInternalEnergy_dC[jc];
303 real64 const oneMinusPoro = 1 - porosity;
306 stack.
energyIncrement += oneMinusPoro * m_rockInternalEnergy( k, 0 ) - ( 1 - porosity_n ) * m_rockInternalEnergy_n( k, 0 );
309 stack.
dEnergyIncrement_dTemperature += -dPorosity_dTemperature * m_rockInternalEnergy( k, 0 ) + oneMinusPoro * m_dRockInternalEnergy_dTemperature( k, 0 );
312 template<
typename SUBREGION_TYPE,
313 typename CONSTITUTIVE_TYPE,
319 real64 const & porosity_n,
322 using Deriv = constitutive::multifluid::DerivativeOffset;
324 Base::computePoreVolumeConstraint( k,
328 arraySlice2d<
real64 const, compflow::USD_PHASE_DC - 1 >
const dPhaseVolFrac = m_dFluidPhaseVolFrac[k];
331 for(
integer ip = 0; ip < m_numPhases; ++ip )
337 template<
typename SUBREGION_TYPE,
338 typename CONSTITUTIVE_TYPE,
344 real64 const ( &dNdX )[numNodesPerElem][3],
348 using namespace PDEUtilities;
350 Base::assembleMomentumBalanceTerms( N, dNdX, detJxW, stack );
352 constexpr FunctionSpace displacementTrialSpace = FE_TYPE::template getFunctionSpace< numDofPerTrialSupportPoint >();
353 constexpr FunctionSpace displacementTestSpace = displacementTrialSpace;
354 constexpr FunctionSpace pressureTrialSpace = FunctionSpace::P0;
358 BilinearFormUtilities::compute< displacementTestSpace,
360 DifferentialOperator::SymmetricGradient,
361 DifferentialOperator::Identity >
369 BilinearFormUtilities::compute< displacementTestSpace,
371 DifferentialOperator::Identity,
372 DifferentialOperator::Identity >
381 template<
typename SUBREGION_TYPE,
382 typename CONSTITUTIVE_TYPE,
391 using namespace PDEUtilities;
393 Base::assembleElementBasedFlowTerms( dNdX, detJxW, stack );
395 constexpr FunctionSpace displacementTrialSpace = FE_TYPE::template getFunctionSpace< numDofPerTrialSupportPoint >();
396 constexpr FunctionSpace pressureTrialSpace = FunctionSpace::P0;
397 constexpr FunctionSpace pressureTestSpace = pressureTrialSpace;
401 BilinearFormUtilities::compute< pressureTestSpace,
403 DifferentialOperator::Identity,
404 DifferentialOperator::Identity >
414 BilinearFormUtilities::compute< pressureTestSpace,
416 DifferentialOperator::Identity,
417 DifferentialOperator::Identity >
427 LinearFormUtilities::compute< pressureTestSpace,
428 DifferentialOperator::Identity >
435 BilinearFormUtilities::compute< pressureTestSpace,
436 displacementTrialSpace,
437 DifferentialOperator::Identity,
438 DifferentialOperator::Divergence >
446 BilinearFormUtilities::compute< pressureTestSpace,
448 DifferentialOperator::Identity,
449 DifferentialOperator::Identity >
457 BilinearFormUtilities::compute< pressureTestSpace,
459 DifferentialOperator::Identity,
460 DifferentialOperator::Identity >
468 BilinearFormUtilities::compute< pressureTestSpace,
470 DifferentialOperator::Identity,
471 DifferentialOperator::Identity >
481 template<
typename SUBREGION_TYPE,
482 typename CONSTITUTIVE_TYPE,
489 StackVariables & stack )
const
493 real64 N[numNodesPerElem]{};
494 real64 dNdX[numNodesPerElem][3]{};
495 FE_TYPE::calcN( q, stack.feStack, N );
496 real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal,
497 stack.feStack, dNdX );
500 LvArray::tensorOps::fill< 6 >( stack.strainIncrement, 0.0 );
501 FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement );
506 smallStrainUpdate( k, q, stack );
510 assembleMomentumBalanceTerms( N, dNdX, detJxW, stack );
514 assembleElementBasedFlowTerms( dNdX, detJxW, stack );
517 template<
typename SUBREGION_TYPE,
518 typename CONSTITUTIVE_TYPE,
526 using namespace compositionalMultiphaseUtilities;
528 real64 const maxForce = Base::complete( k, stack );
531 m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack );
532 integer numDisplacementDofs = numSupportPoints * numDofPerTestSupportPoint;
534 if( m_useTotalMassEquation > 0 )
537 real64 work[maxNumComponents + 1]{};
543 for(
int localNode = 0; localNode < numSupportPoints; ++localNode )
545 for(
integer dim = 0; dim < numDofPerTestSupportPoint; ++dim )
547 localIndex const dof = LvArray::integerConversion< localIndex >( stack.localRowDofIndex[numDofPerTestSupportPoint*localNode + dim] - m_dofRankOffset );
550 if( dof < 0 || dof >= m_matrix.numRows() )
555 m_matrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( dof,
565 if( 0 <= massDof && massDof < m_matrix.numRows() )
570 for(
localIndex i = 0; i < m_numComponents; ++i )
572 m_matrix.template addToRow< serialAtomic >( massDof + i,
580 m_matrix.template addToRow< serialAtomic >( massDof + m_numComponents,
591 if( 0 <= energyDof && energyDof < m_matrix.numRows() )
593 m_matrix.template addToRowBinarySearchUnsorted< serialAtomic >( energyDof,
594 stack.localRowDofIndex,
596 numDisplacementDofs );
597 m_matrix.template addToRow< serialAtomic >( energyDof,
601 m_matrix.template addToRow< serialAtomic >( energyDof,
605 m_matrix.template addToRow< serialAtomic >( energyDof,
606 stack.localComponentDofIndices,
616 template<
typename SUBREGION_TYPE,
617 typename CONSTITUTIVE_TYPE,
619 template<
typename POLICY,
620 typename KERNEL_TYPE >
623 KERNEL_TYPE
const & kernelComponent )
628 RAJA::ReduceMax< ReducePolicy< POLICY >,
real64 > maxResidual( 0 );
630 forAll< POLICY >( numElems,
633 typename KERNEL_TYPE::StackVariables stack;
635 kernelComponent.setup( k, stack );
636 for(
integer q=0; q<KERNEL_TYPE::numQuadraturePointsPerElem; ++q )
638 kernelComponent.quadraturePointKernel( k, q, stack );
640 maxResidual.max( kernelComponent.complete( k, stack ) );
642 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.
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 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.