GEOS
SolutionScalingZFormulationKernel.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_SOLUTIONSCALINGZFORMULATIONKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_SOLUTIONSCALINGZFORMULATIONKERNEL_HPP
22 
25 
26 namespace geos
27 {
28 
29 namespace isothermalCompositionalMultiphaseBaseKernels
30 {
31 
32 /******************************** SolutionScalingZFormulationKernel ********************************/
33 
39 {
40 public:
41 
43  using Base::m_rankOffset;
44  using Base::m_numComp;
45  using Base::m_dofNumber;
46  using Base::m_ghostRank;
48  using Base::m_pressure;
49  using Base::m_compFrac;
51  using Base::m_compFracScalingFactor;
52 
68  SolutionScalingZFormulationKernel( real64 const maxRelativePresChange,
69  real64 const maxAbsolutePresChange,
70  real64 const maxCompFracChange,
71  globalIndex const rankOffset,
72  integer const numComp,
73  string const dofKey,
74  ElementSubRegionBase const & subRegion,
75  arrayView1d< real64 const > const localSolution,
76  arrayView1d< real64 const > const pressure,
78  arrayView1d< real64 > pressureScalingFactor,
79  arrayView1d< real64 > compFracScalingFactor )
80  : Base( rankOffset,
81  numComp,
82  dofKey,
83  subRegion,
84  localSolution,
85  pressure,
86  compFrac,
87  pressureScalingFactor,
88  compFracScalingFactor ),
89  m_maxRelativePresChange( maxRelativePresChange ),
90  m_maxAbsolutePresChange( maxAbsolutePresChange ),
91  m_maxCompFracChange( maxCompFracChange )
92  {}
93 
98  struct StackVariables : public Base::StackVariables
99  {
102  { }
103 
104  StackVariables( real64 _localMinVal,
105  real64 _localMaxDeltaPres,
106  real64 _localMaxDeltaTemp,
107  real64 _localMaxDeltaCompFrac,
108  real64 _localMinPresScalingFactor,
109  real64 _localMinTempScalingFactor,
110  real64 _localMinCompFracScalingFactor )
111  :
112  Base::StackVariables( _localMinVal ),
113  localMaxDeltaPres( _localMaxDeltaPres ),
114  localMaxDeltaTemp( _localMaxDeltaTemp ),
115  localMaxDeltaCompFrac( _localMaxDeltaCompFrac ),
116  localMinPresScalingFactor( _localMinPresScalingFactor ),
117  localMinTempScalingFactor( _localMinTempScalingFactor ),
118  localMinCompFracScalingFactor( _localMinCompFracScalingFactor )
119  { }
120 
121  real64 localMaxDeltaPres;
122  real64 localMaxDeltaTemp;
123  real64 localMaxDeltaCompFrac;
124 
125  real64 localMinPresScalingFactor;
126  real64 localMinTempScalingFactor;
127  real64 localMinCompFracScalingFactor;
128 
129  };
130 
138  template< typename POLICY, typename KERNEL_TYPE >
139  static StackVariables
140  launch( localIndex const numElems,
141  KERNEL_TYPE const & kernelComponent )
142  {
143  RAJA::ReduceMin< ReducePolicy< POLICY >, real64 > globalScalingFactor( 1.0 );
144 
145  RAJA::ReduceMax< ReducePolicy< POLICY >, real64 > maxDeltaPres( 0.0 );
146  RAJA::ReduceMax< ReducePolicy< POLICY >, real64 > maxDeltaTemp( 0.0 );
147  RAJA::ReduceMax< ReducePolicy< POLICY >, real64 > maxDeltaCompFrac( 0.0 );
148 
149  RAJA::ReduceMin< ReducePolicy< POLICY >, real64 > minPresScalingFactor( 1.0 );
150  RAJA::ReduceMin< ReducePolicy< POLICY >, real64 > minTempScalingFactor( 1.0 );
151  RAJA::ReduceMin< ReducePolicy< POLICY >, real64 > minCompFracScalingFactor( 1.0 );
152 
153  forAll< POLICY >( numElems, [=] GEOS_HOST_DEVICE ( localIndex const ei )
154  {
155  if( kernelComponent.ghostRank( ei ) >= 0 )
156  {
157  return;
158  }
159 
160  StackVariables stack;
161  kernelComponent.setup( ei, stack );
162  kernelComponent.compute( ei, stack );
163 
164  globalScalingFactor.min( stack.localMinVal );
165 
166  maxDeltaPres.max( stack.localMaxDeltaPres );
167  maxDeltaTemp.max( stack.localMaxDeltaTemp );
168  maxDeltaCompFrac.max( stack.localMaxDeltaCompFrac );
169 
170  minPresScalingFactor.min( stack.localMinPresScalingFactor );
171  minTempScalingFactor.min( stack.localMinTempScalingFactor );
172  minCompFracScalingFactor.min( stack.localMinCompFracScalingFactor );
173  } );
174 
175  return StackVariables( globalScalingFactor.get(),
176  maxDeltaPres.get(),
177  maxDeltaTemp.get(),
178  maxDeltaCompFrac.get(),
179  minPresScalingFactor.get(),
180  minTempScalingFactor.get(),
181  minCompFracScalingFactor.get() );
182  }
183 
185  void setup( localIndex const ei,
186  StackVariables & stack ) const
187  {
188  Base::setup( ei, stack );
189 
190  stack.localMaxDeltaPres = 0.0;
191  stack.localMaxDeltaTemp = 0.0;
192  stack.localMaxDeltaCompFrac = 0.0;
193 
194  stack.localMinPresScalingFactor = 1.0;
195  stack.localMinTempScalingFactor = 1.0;
196  stack.localMinCompFracScalingFactor = 1.0;
197  }
198 
205  void compute( localIndex const ei,
206  StackVariables & stack ) const
207  {
208  computeScalingFactor( ei, stack );
209  }
210 
218  template< typename FUNC = NoOpFunc >
221  StackVariables & stack,
222  FUNC && kernelOp = NoOpFunc{} ) const
223  {
224  real64 constexpr eps = minDensForDivision;
225 
226  // compute the change in pressure
227  real64 const pres = m_pressure[ei];
228  real64 const absPresChange = LvArray::math::abs( m_localSolution[stack.localRow] );
229  if( stack.localMaxDeltaPres < absPresChange )
230  {
231  stack.localMaxDeltaPres = absPresChange;
232  }
233 
234  // compute pressure scaling factor
235  real64 presScalingFactor = 1.0;
236  // when enabled, absolute change scaling has a priority over relative change
237  if( m_maxAbsolutePresChange > 0.0 ) // maxAbsolutePresChange <= 0.0 means that absolute scaling is disabled
238  {
239  if( absPresChange > m_maxAbsolutePresChange )
240  {
241  presScalingFactor = m_maxAbsolutePresChange / absPresChange;
242  }
243  }
244  else if( pres > eps )
245  {
246  real64 const relativePresChange = absPresChange / pres;
247  if( relativePresChange > m_maxRelativePresChange )
248  {
249  presScalingFactor = m_maxRelativePresChange / relativePresChange;
250  }
251  }
252  m_pressureScalingFactor[ei] = presScalingFactor;
253  if( stack.localMinVal > presScalingFactor )
254  {
255  stack.localMinVal = presScalingFactor;
256  }
257  if( stack.localMinPresScalingFactor > presScalingFactor )
258  {
259  stack.localMinPresScalingFactor = presScalingFactor;
260  }
261 
262  // Component Fraction Change Scaling
263  m_compFracScalingFactor[ei] = 1.0;
264 
265  for( integer ic = 0; ic < m_numComp; ++ic )
266  {
267  // compute scaling factor based on relative change in component densities
268  real64 const absCompFracChange = LvArray::math::abs( m_localSolution[stack.localRow + ic + 1] );
269  if( stack.localMaxDeltaCompFrac < absCompFracChange )
270  {
271  stack.localMaxDeltaCompFrac = absCompFracChange;
272  }
273 
274  if( absCompFracChange > m_maxCompFracChange && absCompFracChange > eps )
275  {
276  real64 const compScalingFactor = m_maxCompFracChange / absCompFracChange;
277  m_compFracScalingFactor[ei] = LvArray::math::min( m_compFracScalingFactor[ei], compScalingFactor );
278  if( stack.localMinVal > compScalingFactor )
279  {
280  stack.localMinVal = compScalingFactor;
281  }
282  if( stack.localMinCompFracScalingFactor > compScalingFactor )
283  {
284  stack.localMinCompFracScalingFactor = compScalingFactor;
285  }
286  }
287  }
288 
289  // compute the scaling factor for other vars, such as temperature
290  kernelOp();
291  }
292 
293 protected:
294 
297  real64 const m_maxAbsolutePresChange;
298  real64 const m_maxCompFracChange;
299 
300 };
301 
306 {
307 public:
308 
309  /*
310  * @brief Create and launch the kernel computing the scaling factor
311  * @tparam POLICY the kernel policy
312  * @param[in] maxRelativePresChange the max allowed relative pressure change
313  * @param[in] maxAbsolutePresChange the max allowed absolute pressure change
314  * @param[in] maxCompFracChange the max allowed comp fraction change
315  * @param[in] rankOffset the rank offset
316  * @param[in] numComp the number of components
317  * @param[in] dofKey the dof key to get dof numbers
318  * @param[in] subRegion the subRegion
319  * @param[in] localSolution the Newton update
320  * @return the scaling factor
321  */
322  template< typename POLICY >
324  createAndLaunch( real64 const maxRelativePresChange,
325  real64 const maxAbsolutePresChange,
326  real64 const maxCompFracChange,
327  arrayView1d< real64 const > const pressure,
329  arrayView1d< real64 > pressureScalingFactor,
330  arrayView1d< real64 > compFracScalingFactor,
331  globalIndex const rankOffset,
332  integer const numComp,
333  string const dofKey,
334  ElementSubRegionBase & subRegion,
335  arrayView1d< real64 const > const localSolution )
336  {
337  SolutionScalingZFormulationKernel kernel( maxRelativePresChange, maxAbsolutePresChange, maxCompFracChange, rankOffset,
338  numComp, dofKey, subRegion, localSolution, pressure, compFrac, pressureScalingFactor, compFracScalingFactor );
339  return SolutionScalingZFormulationKernel::launch< POLICY >( subRegion.size(), kernel );
340  }
341 };
342 
343 } // namespace isothermalCompositionalMultiphaseBaseKernels
344 
345 } // namespace geos
346 
347 
348 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_SOLUTIONSCALINGZFORMULATIONKERNEL_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
Definition: Group.hpp:1317
GEOS_HOST_DEVICE void setup(localIndex const ei, StackVariables &stack) const
Performs the setup phase for the kernel.
GEOS_HOST_DEVICE void computeScalingFactor(localIndex const ei, StackVariables &stack, FUNC &&kernelOp=NoOpFunc{}) const
Compute the local value of the scaling factor.
static StackVariables launch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
SolutionScalingZFormulationKernel(real64 const maxRelativePresChange, real64 const maxAbsolutePresChange, real64 const maxCompFracChange, globalIndex const rankOffset, integer const numComp, string const dofKey, ElementSubRegionBase const &subRegion, arrayView1d< real64 const > const localSolution, arrayView1d< real64 const > const pressure, arrayView2d< real64 const, compflow::USD_COMP > const compFrac, arrayView1d< real64 > pressureScalingFactor, arrayView1d< real64 > compFracScalingFactor)
Create a new kernel instance.
GEOS_HOST_DEVICE void compute(localIndex const ei, StackVariables &stack) const
Compute the local value.
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