GEOS
ThermalHydrostaticPressureKernel.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 TotalEnergies
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_SINGLEPHASE_THERMALHYDROSTATICPRESSUREKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_THERMALHYDROSTATICPRESSUREKERNEL_HPP
22 
23 #include "common/DataTypes.hpp"
24 #include "common/GEOS_RAJA_Interface.hpp"
25 #include "constitutive/fluid/singlefluid/SingleFluidBase.hpp"
26 
27 namespace geos
28 {
29 
30 namespace thermalSinglePhaseBaseKernels
31 {
32 
33 /******************************** HydrostaticPressureKernel ********************************/
34 
36 {
37 
38  template< typename FLUID_WRAPPER >
39  static bool
40  computeHydrostaticPressure( integer const maxNumEquilIterations,
41  real64 const & equilTolerance,
42  real64 const (&gravVector)[ 3 ],
43  FLUID_WRAPPER fluidWrapper,
44  TableFunction::KernelWrapper tempTableWrapper,
45  real64 const & refElevation,
46  real64 const & refPres,
47  real64 const & refDens,
48  real64 const & newElevation,
49  real64 & newPres,
50  real64 & newDens )
51  {
52  // Step 1: guess the pressure with the refDensity
53 
54  real64 const gravCoef = gravVector[2] * ( refElevation - newElevation );
55  real64 const temp = tempTableWrapper.compute( &newElevation );
56  real64 pres0 = refPres - refDens * gravCoef;
57  real64 pres1 = 0.0;
58 
59  // Step 2: compute the mass density at this elevation using the guess, and update pressure
60 
61  real64 dens = 0.0;
62  real64 visc = 0.0;
63  constitutive::SingleFluidBaseUpdate::computeThermalValues( fluidWrapper,
64  pres0,
65  temp,
66  dens,
67  visc );
68  pres1 = refPres - 0.5 * ( refDens + dens ) * gravCoef;
69 
70  // Step 3: fixed-point iteration until convergence
71 
72  bool equilHasConverged = false;
73  for( localIndex eqIter = 0; eqIter < maxNumEquilIterations; ++eqIter )
74  {
75 
76  // check convergence
77  equilHasConverged = ( LvArray::math::abs( pres0 - pres1 ) < equilTolerance );
78  pres0 = pres1;
79 
80  // if converged, move on
81  if( equilHasConverged )
82  {
83  break;
84  }
85 
86  // compute the density at this elevation using the previous pressure, and compute the new pressure
87  constitutive::SingleFluidBaseUpdate::computeThermalValues( fluidWrapper,
88  pres0,
89  temp,
90  dens,
91  visc );
92  pres1 = refPres - 0.5 * ( refDens + dens ) * gravCoef;
93  }
94 
95  // Step 4: save the hydrostatic pressure and the corresponding density
96 
97  newPres = pres1;
98  newDens = dens;
99 
100  return equilHasConverged;
101  }
102 
103 
104  template< typename FLUID_WRAPPER >
105  static bool
106  launch( localIndex const size,
107  integer const maxNumEquilIterations,
108  real64 const equilTolerance,
109  real64 const (&gravVector)[ 3 ],
110  real64 const & minElevation,
111  real64 const & elevationIncrement,
112  real64 const & datumElevation,
113  real64 const & datumPres,
114  FLUID_WRAPPER fluidWrapper,
115  TableFunction::KernelWrapper tempTableWrapper,
116  arrayView1d< arrayView1d< real64 > const > elevationValues,
117  arrayView1d< real64 > pressureValues )
118  {
119  bool hasConverged = true;
120 
121  // Step 1: compute the mass density at the datum elevation
122 
123  real64 datumDens = 0.0;
124  real64 datumVisc = 0.0;
125  real64 const datumTemp = tempTableWrapper.compute( &datumElevation );
126 
127  constitutive::SingleFluidBaseUpdate::computeThermalValues( fluidWrapper,
128  datumPres,
129  datumTemp,
130  datumDens,
131  datumVisc );
132 
133  // Step 2: find the closest elevation to datumElevation
134 
135  forAll< parallelHostPolicy >( size, [=] ( localIndex const i )
136  {
137  real64 const elevation = minElevation + i * elevationIncrement;
138  elevationValues[0][i] = elevation;
139  } );
140  integer const iRef = LvArray::sortedArrayManipulation::find( elevationValues[0].begin(),
141  elevationValues[0].size(),
142  datumElevation );
143 
144 
145  // Step 3: compute the mass density and pressure at the reference elevation
146 
147  array1d< real64 > dens( pressureValues.size() );
148 
149  bool const hasConvergedRef =
150  computeHydrostaticPressure( maxNumEquilIterations,
151  equilTolerance,
152  gravVector,
153  fluidWrapper,
154  tempTableWrapper,
155  datumElevation,
156  datumPres,
157  datumDens,
158  elevationValues[0][iRef],
159  pressureValues[iRef],
160  dens[iRef] );
161  if( !hasConvergedRef )
162  {
163  return false;
164  }
165 
166 
167  // Step 4: for each elevation above the reference elevation, compute the pressure
168 
169  localIndex const numEntriesAboveRef = size - iRef - 1;
170  forAll< serialPolicy >( numEntriesAboveRef, [=, &hasConverged] ( localIndex const i )
171  {
172  bool const hasConvergedAboveRef =
173  computeHydrostaticPressure( maxNumEquilIterations,
174  equilTolerance,
175  gravVector,
176  fluidWrapper,
177  tempTableWrapper,
178  elevationValues[0][iRef+i],
179  pressureValues[iRef+i],
180  dens[iRef+i],
181  elevationValues[0][iRef+i+1],
182  pressureValues[iRef+i+1],
183  dens[iRef+i+1] );
184  if( !hasConvergedAboveRef )
185  {
186  hasConverged = false;
187  }
188 
189 
190  } );
191 
192  // Step 5: for each elevation below the reference elevation, compute the pressure
193 
194  localIndex const numEntriesBelowRef = iRef;
195  forAll< serialPolicy >( numEntriesBelowRef, [=, &hasConverged] ( localIndex const i )
196  {
197  bool const hasConvergedBelowRef =
198  computeHydrostaticPressure( maxNumEquilIterations,
199  equilTolerance,
200  gravVector,
201  fluidWrapper,
202  tempTableWrapper,
203  elevationValues[0][iRef-i],
204  pressureValues[iRef-i],
205  dens[iRef-i],
206  elevationValues[0][iRef-i-1],
207  pressureValues[iRef-i-1],
208  dens[iRef-i-1] );
209  if( !hasConvergedBelowRef )
210  {
211  hasConverged = false;
212  }
213  } );
214 
215  return hasConverged;
216  }
217 };
218 
219 } // namespace thermalSinglePhaseBaseKernels
220 
221 } // namespace geos
222 
223 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_THERMALHYDROSTATICPRESSUREKERNEL_HPP
GEOS_HOST_DEVICE real64 compute(IN_ARRAY const &input) const
Interpolate in the table.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:179
double real64
64-bit floating point type.
Definition: DataTypes.hpp:98
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:84
int integer
Signed integer type.
Definition: DataTypes.hpp:81
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:175