GEOS
SolutionCheckKernel.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_SOLUTIONCHECKKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_SOLUTIONCHECKKERNEL_HPP
22 
24 
25 namespace geos
26 {
27 
28 namespace isothermalCompositionalMultiphaseBaseKernels
29 {
30 
31 /******************************** SolutionCheckKernel ********************************/
32 
38 {
39 public:
40 
42  using Base::m_rankOffset;
43  using Base::m_numComp;
44  using Base::m_dofNumber;
45  using Base::m_ghostRank;
47  using Base::m_pressure;
48  using Base::m_compDens;
49 
62  SolutionCheckKernel( integer const allowCompDensChopping,
63  integer const allowNegativePressure,
65  real64 const scalingFactor,
66  arrayView1d< real64 const > const pressure,
68  arrayView1d< real64 > pressureScalingFactor,
69  arrayView1d< real64 > compDensScalingFactor,
70  globalIndex const rankOffset,
71  integer const numComp,
72  string const dofKey,
73  ElementSubRegionBase const & subRegion,
74  arrayView1d< real64 const > const localSolution )
75  : Base( rankOffset,
76  numComp,
77  dofKey,
78  subRegion,
79  localSolution,
80  pressure,
81  compDens,
82  pressureScalingFactor,
83  compDensScalingFactor ),
84  m_allowCompDensChopping( allowCompDensChopping ),
85  m_allowNegativePressure( allowNegativePressure ),
86  m_scalingFactor( scalingFactor ),
87  m_scalingType( scalingType )
88  {}
89 
94  struct StackVariables : public Base::StackVariables
95  {
98  { }
99 
100  StackVariables( real64 _localMinVal,
101  real64 _localMinPres,
102  real64 _localMinDens,
103  real64 _localMinTotalDens,
104  integer _localNumNegPressures,
105  integer _localNumNegDens,
106  integer _localNumNegTotalDens )
107  :
108  Base::StackVariables( _localMinVal ),
109  localMinPres( _localMinPres ),
110  localMinDens( _localMinDens ),
111  localMinTotalDens( _localMinTotalDens ),
112  localNumNegPressures( _localNumNegPressures ),
113  localNumNegDens( _localNumNegDens ),
114  localNumNegTotalDens( _localNumNegTotalDens )
115  { }
116 
117  real64 localMinPres;
118  real64 localMinDens;
119  real64 localMinTotalDens;
120 
121  integer localNumNegPressures;
122  integer localNumNegDens;
123  integer localNumNegTotalDens;
124 
125  };
126 
134  template< typename POLICY, typename KERNEL_TYPE >
135  static StackVariables
136  launch( localIndex const numElems,
137  KERNEL_TYPE const & kernelComponent )
138  {
139  RAJA::ReduceMin< ReducePolicy< POLICY >, integer > globalMinVal( 1 );
140 
141  RAJA::ReduceMin< ReducePolicy< POLICY >, real64 > minPres( 0.0 );
142  RAJA::ReduceMin< ReducePolicy< POLICY >, real64 > minDens( 0.0 );
143  RAJA::ReduceMin< ReducePolicy< POLICY >, real64 > minTotalDens( 0.0 );
144 
145  RAJA::ReduceSum< ReducePolicy< POLICY >, integer > numNegPressures( 0 );
146  RAJA::ReduceSum< ReducePolicy< POLICY >, integer > numNegDens( 0 );
147  RAJA::ReduceSum< ReducePolicy< POLICY >, integer > numNegTotalDens( 0 );
148 
149  forAll< POLICY >( numElems, [=] GEOS_HOST_DEVICE ( localIndex const ei )
150  {
151  if( kernelComponent.ghostRank( ei ) >= 0 )
152  {
153  return;
154  }
155 
156  StackVariables stack;
157  kernelComponent.setup( ei, stack );
158  kernelComponent.compute( ei, stack );
159 
160  globalMinVal.min( stack.localMinVal );
161 
162  minPres.min( stack.localMinPres );
163  minDens.min( stack.localMinDens );
164  minTotalDens.min( stack.localMinTotalDens );
165 
166  numNegPressures += stack.localNumNegPressures;
167  numNegDens += stack.localNumNegDens;
168  numNegTotalDens += stack.localNumNegTotalDens;
169  } );
170 
171  return StackVariables( globalMinVal.get(),
172  minPres.get(),
173  minDens.get(),
174  minTotalDens.get(),
175  numNegPressures.get(),
176  numNegDens.get(),
177  numNegTotalDens.get() );
178  }
179 
181  void setup( localIndex const ei,
182  StackVariables & stack ) const
183  {
184  Base::setup( ei, stack );
185 
186  stack.localMinPres = 0.0;
187  stack.localMinDens = 0.0;
188  stack.localMinTotalDens = 0.0;
189 
190  stack.localNumNegPressures = 0;
191  stack.localNumNegDens = 0;
192  stack.localNumNegTotalDens = 0;
193  }
194 
201  void compute( localIndex const ei,
202  StackVariables & stack ) const
203  {
204  computeSolutionCheck( ei, stack );
205  }
206 
214  template< typename FUNC = NoOpFunc >
217  StackVariables & stack,
218  FUNC && kernelOp = NoOpFunc{} ) const
219  {
221 
222  real64 const newPres = m_pressure[ei] + (localScaling ? m_pressureScalingFactor[ei] : m_scalingFactor) * m_localSolution[stack.localRow];
223  if( newPres < 0 )
224  {
226  {
227  stack.localMinVal = 0;
228  }
229  stack.localNumNegPressures += 1;
230  if( newPres < stack.localMinPres )
231  stack.localMinPres = newPres;
232  }
233 
234  // if component density chopping is not allowed, the time step fails if a component density is negative
235  // otherwise, we just check that the total density is positive, and negative component densities
236  // will be chopped (i.e., set to zero) in ApplySystemSolution)
238  {
239  for( integer ic = 0; ic < m_numComp; ++ic )
240  {
241  real64 const newDens = m_compDens[ei][ic] + (localScaling ? m_compDensScalingFactor[ei] : m_scalingFactor) * m_localSolution[stack.localRow + ic + 1];
242  if( newDens < 0 )
243  {
244  stack.localMinVal = 0;
245  stack.localNumNegDens += 1;
246  if( newDens < stack.localMinDens )
247  stack.localMinDens = newDens;
248  }
249  }
250  }
251  else
252  {
253  real64 totalDens = 0.0;
254  for( integer ic = 0; ic < m_numComp; ++ic )
255  {
256  real64 const newDens = m_compDens[ei][ic] + (localScaling ? m_compDensScalingFactor[ei] : m_scalingFactor) * m_localSolution[stack.localRow + ic + 1];
257  totalDens += ( newDens > 0.0 ) ? newDens : 0.0;
258  }
259  if( totalDens < 0 )
260  {
261  stack.localMinVal = 0;
262  stack.localNumNegTotalDens += 1;
263  if( totalDens < stack.localMinTotalDens )
264  stack.localMinTotalDens = totalDens;
265  }
266  }
267 
268  kernelOp();
269  }
270 
271 protected:
272 
275 
278 
281 
284 
285 };
286 
291 {
292 public:
293 
305  template< typename POLICY >
307  createAndLaunch( integer const allowCompDensChopping,
308  integer const allowNegativePressure,
309  CompositionalMultiphaseFVM::ScalingType const scalingType,
310  real64 const scalingFactor,
311  arrayView1d< real64 const > const pressure,
313  arrayView1d< real64 > pressureScalingFactor,
314  arrayView1d< real64 > compDensScalingFactor,
315  globalIndex const rankOffset,
316  integer const numComp,
317  string const dofKey,
318  ElementSubRegionBase & subRegion,
319  arrayView1d< real64 const > const localSolution )
320  {
321  SolutionCheckKernel kernel( allowCompDensChopping, allowNegativePressure, scalingType, scalingFactor,
322  pressure, compDens, pressureScalingFactor, compDensScalingFactor, rankOffset,
323  numComp, dofKey, subRegion, localSolution );
324  return SolutionCheckKernel::launch< POLICY >( subRegion.size(), kernel );
325  }
326 
327 };
328 
329 } // namespace isothermalCompositionalMultiphaseBaseKernels
330 
331 } // namespace geos
332 
333 
334 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_SOLUTIONCHECKKERNEL_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
@ Local
Scale the Newton update locally (modifies the Newton direction)
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
Definition: Group.hpp:1315
static SolutionCheckKernel::StackVariables createAndLaunch(integer const allowCompDensChopping, integer const allowNegativePressure, CompositionalMultiphaseFVM::ScalingType const scalingType, real64 const scalingFactor, arrayView1d< real64 const > const pressure, arrayView2d< real64 const, compflow::USD_COMP > const compDens, arrayView1d< real64 > pressureScalingFactor, arrayView1d< real64 > compDensScalingFactor, globalIndex const rankOffset, integer const numComp, string const dofKey, ElementSubRegionBase &subRegion, arrayView1d< real64 const > const localSolution)
Create a new kernel and launch.
GEOS_HOST_DEVICE void computeSolutionCheck(localIndex const ei, StackVariables &stack, FUNC &&kernelOp=NoOpFunc{}) const
Compute the local value of the check.
integer const m_allowNegativePressure
flag to allow negative pressure values
SolutionCheckKernel(integer const allowCompDensChopping, integer const allowNegativePressure, CompositionalMultiphaseFVM::ScalingType const scalingType, real64 const scalingFactor, arrayView1d< real64 const > const pressure, arrayView2d< real64 const, compflow::USD_COMP > const compDens, arrayView1d< real64 > pressureScalingFactor, arrayView1d< real64 > compDensScalingFactor, globalIndex const rankOffset, integer const numComp, string const dofKey, ElementSubRegionBase const &subRegion, arrayView1d< real64 const > const localSolution)
Create a new kernel instance.
GEOS_HOST_DEVICE void compute(localIndex const ei, StackVariables &stack) const
Compute the local value.
static StackVariables launch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
CompositionalMultiphaseFVM::ScalingType const m_scalingType
scaling type (global or local)
integer const m_allowCompDensChopping
flag to allow the component density chopping
GEOS_HOST_DEVICE void setup(localIndex const ei, StackVariables &stack) const
Performs the setup phase for the kernel.
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