GEOS
ThermalResidualNormKernel.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2024 Total, S.A
7  * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
8  * Copyright (c) 2023-2024 Chevron
9  * Copyright (c) 2019- GEOS/GEOSX Contributors
10  * All rights reserved
11  *
12  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
13  * ------------------------------------------------------------------------------------------------------------
14  */
15 
20 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_THERMALRESIDUALNORMKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_THERMALRESIDUALNORMKERNEL_HPP
22 
24 
25 namespace geos
26 {
27 
28 namespace thermalCompositionalMultiphaseBaseKernels
29 {
30 
31 /******************************** ResidualNormKernel ********************************/
32 
37 {
38 public:
39 
40  using Base = ResidualNormKernelBase< 3 >;
41  using Base::m_minNormalizer;
42  using Base::m_rankOffset;
43  using Base::m_localResidual;
44  using Base::m_dofNumber;
45 
46  ResidualNormKernel( globalIndex const rankOffset,
47  arrayView1d< real64 const > const & localResidual,
48  arrayView1d< globalIndex const > const & dofNumber,
50  integer const numComponents,
51  integer const numPhases,
52  ElementSubRegionBase const & subRegion,
53  constitutive::MultiFluidBase const & fluid,
54  constitutive::CoupledSolidBase const & solid,
55  constitutive::SolidInternalEnergy const & solidInternalEnergy,
56  real64 const minNormalizer )
57  : Base( rankOffset,
58  localResidual,
59  dofNumber,
60  ghostRank,
61  minNormalizer ),
62  m_numComponents( numComponents ),
63  m_numPhases( numPhases ),
64  m_volume( subRegion.getElementVolume() ),
65  m_porosity_n( solid.getPorosity_n() ),
66  m_phaseVolFrac_n( subRegion.getField< fields::flow::phaseVolumeFraction_n >() ),
67  m_totalDens_n( fluid.totalDensity_n() ),
68  m_phaseDens_n( fluid.phaseDensity_n() ),
69  m_phaseInternalEnergy_n( fluid.phaseInternalEnergy_n() ),
70  m_solidInternalEnergy_n( solidInternalEnergy.getInternalEnergy_n() )
71  {}
72 
74  void computeMassEnergyNormalizers( localIndex const ei,
75  real64 & massNormalizer,
76  real64 & energyNormalizer ) const
77  {
78  massNormalizer = LvArray::math::max( m_minNormalizer, m_totalDens_n[ei][0] * m_porosity_n[ei][0] * m_volume[ei] );
79  real64 const poreVolume = m_porosity_n[ei][0] * m_volume[ei];
80  energyNormalizer = m_solidInternalEnergy_n[ei][0] * ( 1.0 - m_porosity_n[ei][0] ) * m_volume[ei];
81  for( integer ip = 0; ip < m_numPhases; ++ip )
82  {
83  energyNormalizer += m_phaseInternalEnergy_n[ei][0][ip] * m_phaseDens_n[ei][0][ip] * m_phaseVolFrac_n[ei][ip] * poreVolume;
84  }
85  // warning: internal energy can be negative
86  energyNormalizer = LvArray::math::max( m_minNormalizer, LvArray::math::abs( energyNormalizer ) );
87  }
88 
90  virtual void computeLinf( localIndex const ei,
91  LinfStackVariables & stack ) const override
92  {
93  real64 massNormalizer = 0.0, energyNormalizer = 0.0;
94  computeMassEnergyNormalizers( ei, massNormalizer, energyNormalizer );
95  real64 const volumeNormalizer = LvArray::math::max( m_minNormalizer, m_porosity_n[ei][0] * m_volume[ei] );
96 
97  // step 1: mass residual
98 
99  for( integer idof = 0; idof < m_numComponents; ++idof )
100  {
101  real64 const valMass = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / massNormalizer;
102  if( valMass > stack.localValue[0] )
103  {
104  stack.localValue[0] = valMass;
105  }
106  }
107 
108  // step 2: volume residual
109 
110  real64 const valVol = LvArray::math::abs( m_localResidual[stack.localRow + m_numComponents] ) / volumeNormalizer;
111  if( valVol > stack.localValue[1] )
112  {
113  stack.localValue[1] = valVol;
114  }
115 
116  // step 3: energy residual
117 
118  real64 const valEnergy = LvArray::math::abs( m_localResidual[stack.localRow + m_numComponents + 1] ) / energyNormalizer;
119  if( valEnergy > stack.localValue[2] )
120  {
121  stack.localValue[2] = valEnergy;
122  }
123  }
124 
126  virtual void computeL2( localIndex const ei,
127  L2StackVariables & stack ) const override
128  {
129  // note: for the L2 norm, we bundle the volume and mass residuals/normalizers
130  real64 massNormalizer = 0.0, energyNormalizer = 0.0;
131  computeMassEnergyNormalizers( ei, massNormalizer, energyNormalizer );
132 
133  // step 1: mass residual
134 
135  for( integer idof = 0; idof < m_numComponents; ++idof )
136  {
137  stack.localValue[0] += m_localResidual[stack.localRow + idof] * m_localResidual[stack.localRow + idof];
138  stack.localNormalizer[0] += massNormalizer;
139  }
140 
141  // step 2: volume residual
142 
143  real64 const valVol = m_localResidual[stack.localRow + m_numComponents] * m_totalDens_n[ei][0]; // we need a mass here, hence the
144  // multiplication
145  stack.localValue[1] += valVol * valVol;
146  stack.localNormalizer[1] += massNormalizer;
147 
148  // step 3: energy residual
149 
150  stack.localValue[2] += m_localResidual[stack.localRow + m_numComponents + 1] * m_localResidual[stack.localRow + m_numComponents + 1];
151  stack.localNormalizer[2] += energyNormalizer;
152  }
153 
154 protected:
155 
158 
161 
164 
167 
173 
176 
177 };
178 
183 {
184 public:
185 
202  template< typename POLICY >
203  static void
205  integer const numComps,
206  integer const numPhases,
207  globalIndex const rankOffset,
208  string const & dofKey,
209  arrayView1d< real64 const > const & localResidual,
210  ElementSubRegionBase const & subRegion,
211  constitutive::MultiFluidBase const & fluid,
212  constitutive::CoupledSolidBase const & solid,
213  constitutive::SolidInternalEnergy const & solidInternalEnergy,
214  real64 const minNormalizer,
215  real64 (& residualNorm)[3],
216  real64 (& residualNormalizer)[3] )
217  {
218  arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey );
219  arrayView1d< integer const > const ghostRank = subRegion.ghostRank();
220 
221  ResidualNormKernel kernel( rankOffset, localResidual, dofNumber, ghostRank,
222  numComps, numPhases, subRegion, fluid, solid, solidInternalEnergy, minNormalizer );
223  if( normType == physicsSolverBaseKernels::NormType::Linf )
224  {
225  ResidualNormKernel::launchLinf< POLICY >( subRegion.size(), kernel, residualNorm );
226  }
227  else // L2 norm
228  {
229  ResidualNormKernel::launchL2< POLICY >( subRegion.size(), kernel, residualNorm, residualNormalizer );
230  }
231 
232  }
233 };
234 
235 
236 } // namespace thermalCompositionalMultiphaseBaseKernels
237 
238 } // namespace geos
239 
240 
241 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_THERMALRESIDUALNORMKERNEL_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
NormType
Type of norm used to check convergence TODO: find a way to put this inside the class.
arrayView1d< real64 const > getElementVolume() const
Get the volume of each element in this subregion.
array1d< integer > const & ghostRank()
Get the ghost information of each object.
GEOS_DECLTYPE_AUTO_RETURN getField() const
Get a view to the field associated with a trait from this ObjectManagerBase.
GEOS_DECLTYPE_AUTO_RETURN getReference(LOOKUP_TYPE const &lookup) const
Look up a wrapper and get reference to wrapped object.
Definition: Group.hpp:1273
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
Definition: Group.hpp:1315
Define the base interface for the residual calculations.
real64 const m_minNormalizer
Value used to make sure that normalizers are never zero.
GEOS_HOST_DEVICE integer ghostRank(localIndex const i) const
Getter for the ghost rank.
arrayView1d< real64 const > const m_localResidual
View on the local residual.
static void createAndLaunch(physicsSolverBaseKernels::NormType const normType, integer const numComps, integer const numPhases, globalIndex const rankOffset, string const &dofKey, arrayView1d< real64 const > const &localResidual, ElementSubRegionBase const &subRegion, constitutive::MultiFluidBase const &fluid, constitutive::CoupledSolidBase const &solid, constitutive::SolidInternalEnergy const &solidInternalEnergy, real64 const minNormalizer, real64(&residualNorm)[3], real64(&residualNormalizer)[3])
Create a new kernel and launch.
arrayView2d< real64 const > const m_solidInternalEnergy_n
View on solid properties at the previous converged time step.
arrayView2d< real64 const, compflow::USD_PHASE > const m_phaseVolFrac_n
View on phase properties at the previous converged time step.
arrayView2d< real64 const > const m_porosity_n
View on porosity at the previous converged time step.
virtual GEOS_HOST_DEVICE void computeLinf(localIndex const ei, LinfStackVariables &stack) const override
Compute the local values for the Linf norm.
virtual GEOS_HOST_DEVICE void computeL2(localIndex const ei, L2StackVariables &stack) const override
Compute the local values and normalizer for the L2 norm.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:180
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:88
double real64
64-bit floating point type.
Definition: DataTypes.hpp:99
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:85
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:82
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:196
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:176
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Definition: DataTypes.hpp:212