GEOS
FieldSpecificationOps.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_COMMON_FIELDSPECIFICATIONOPS_HPP
21 #define GEOS_COMMON_FIELDSPECIFICATIONOPS_HPP
22 
23 #include "codingUtilities/traits.hpp"
24 #include "common/DataTypes.hpp"
25 #include "common/GEOS_RAJA_Interface.hpp"
26 
27 namespace geos
28 {
29 
33 struct OpEqual
34 {
42  template< typename T, typename U >
43  GEOS_HOST_DEVICE static inline
44  void apply( T & lhs, U const & rhs )
45  {
46  lhs = static_cast< T >( rhs );
47  }
48 };
49 
53 struct OpAdd
54 {
62  template< typename T, typename U >
63  GEOS_HOST_DEVICE static inline
64  void apply( T & lhs, U const & rhs )
65  {
66  lhs += static_cast< T >( rhs );
67  }
68 };
69 
73 template< typename OP >
75 {
77  using OpType = OP;
78 
90  template< typename T >
92  static inline typename std::enable_if< !traits::is_tensorT< T >, void >::type
94  localIndex const index,
95  integer const component,
96  real64 const value )
97  {
98  GEOS_UNUSED_VAR( component );
99  OP::template apply( field( index ), value );
100  }
101 
114  template< typename T >
116  static inline typename std::enable_if< traits::is_tensorT< T >, void >::type
118  localIndex const index,
119  integer const component,
120  real64 const value )
121  {
122  OP::template apply( field( index )[component], value );
123  }
124 
136  template< typename T >
138  static inline typename std::enable_if< !traits::is_tensorT< T >, void >::type
140  localIndex const index,
141  integer const component,
142  real64 & value )
143  {
144  GEOS_UNUSED_VAR( component );
145  OP::template apply( value, field( index ) );
146  }
147 
159  template< typename T >
161  static inline typename std::enable_if< traits::is_tensorT< T >, void >::type
163  localIndex const index,
164  integer const component,
165  real64 & value )
166  {
167  OP::template apply( value, field( index )[component] );
168  }
169 
182  template< typename T, int USD >
184  static inline typename std::enable_if< !traits::is_tensorT< T >, void >::type
186  localIndex const index,
187  integer const component,
188  real64 const value )
189  {
190  if( component >= 0 )
191  {
192  OP::template apply( field( index, component ), value );
193  }
194  else
195  {
196  for( localIndex a = 0; a < field.size( 1 ); ++a )
197  {
198  OP::template apply( field( index, a ), value );
199  }
200  }
201  }
202 
216  template< typename T, int USD >
218  static inline typename std::enable_if< traits::is_tensorT< T >, void >::type
220  localIndex const index,
221  integer const component,
222  real64 const value )
223  {
224  if( component >= 0 )
225  {
226  for( localIndex a = 0; a < field.size( 1 ); ++a )
227  {
228  OP::template apply( field( index, a )[component], value );
229  }
230  }
231  else
232  {
233  for( localIndex a = 0; a < field.size( 1 ); ++a )
234  {
235  for( localIndex c = 0; c < T::SIZE; ++c )
236  {
237  OP::template apply( field( index, a )[c], value );
238  }
239  }
240  }
241  }
242 
255  template< typename T, int USD >
257  static inline typename std::enable_if< !traits::is_tensorT< T >, void >::type
259  localIndex const index,
260  integer const component,
261  real64 & value )
262  {
263  GEOS_ASSERT( component >= 0 );
264  OP::template apply( value, field( index, component ) );
265  }
266 
277  template< typename T, int USD >
279  static inline typename std::enable_if< traits::is_tensorT< T >, void >::type
281  localIndex const index,
282  integer const component,
283  real64 & value )
284  {
285  GEOS_UNUSED_VAR( field );
286  GEOS_UNUSED_VAR( index );
287  GEOS_UNUSED_VAR( component );
288  GEOS_UNUSED_VAR( value );
289  GEOS_ERROR( "readFieldValue: unsupported operation" );
290  }
291 
304  template< typename T, int USD >
306  static inline typename std::enable_if< !traits::is_tensorT< T >, void >::type
308  localIndex const index,
309  integer const component,
310  real64 const value )
311  {
312  if( component >= 0 )
313  {
314  for( localIndex a = 0; a < field.size( 1 ); ++a )
315  {
316  OP::template apply( field( index, a, component ), value );
317  }
318  }
319  else
320  {
321  for( localIndex a = 0; a < field.size( 1 ); ++a )
322  {
323  for( localIndex b = 0; b < field.size( 2 ); ++b )
324  {
325  OP::template apply( field( index, a, b ), value );
326  }
327  }
328  }
329  }
330 
344  template< typename T, int USD >
346  static inline typename std::enable_if< traits::is_tensorT< T >, void >::type
348  localIndex const index,
349  integer const component,
350  real64 const value )
351  {
352  if( component >= 0 )
353  {
354  for( localIndex a = 0; a < field.size( 1 ); ++a )
355  {
356  for( localIndex b = 0; b < field.size( 2 ); ++b )
357  {
358  OP::template apply( field( index, a, b )[component], value );
359  }
360  }
361  }
362  else
363  {
364  for( localIndex a = 0; a < field.size( 1 ); ++a )
365  {
366  for( localIndex b = 0; b < field.size( 2 ); ++b )
367  {
368  for( localIndex c = 0; c < T::size(); ++c )
369  {
370  OP::template apply( field( index, a, b )[c], value );
371  }
372  }
373  }
374  }
375  }
376 
386  template< typename T, int USD >
388  static inline void
390  localIndex const index,
391  integer const component,
392  real64 & value )
393  {
394  GEOS_UNUSED_VAR( field );
395  GEOS_UNUSED_VAR( index );
396  GEOS_UNUSED_VAR( component );
397  GEOS_UNUSED_VAR( value );
398  GEOS_ERROR( "readFieldValue: unsupported operation" );
399  }
400 
413  template< typename T, int USD >
415  static inline typename std::enable_if< !traits::is_tensorT< T >, void >::type
417  localIndex const index,
418  integer const component,
419  real64 const value )
420  {
421  if( component >= 0 )
422  {
423  for( localIndex a = 0; a < field.size( 1 ); ++a )
424  {
425  for( localIndex b = 0; b < field.size( 2 ); ++b )
426  {
427  OP::template apply( field( index, a, b, component ), value );
428  }
429  }
430  }
431  else
432  {
433  for( localIndex a = 0; a < field.size( 1 ); ++a )
434  {
435  for( localIndex b = 0; b < field.size( 2 ); ++b )
436  {
437  for( localIndex c = 0; c < field.size( 3 ); ++c )
438  {
439  OP::template apply( field( index, a, b, c ), value );
440  }
441  }
442  }
443  }
444  }
445 
459  template< typename T, int USD >
461  static inline typename std::enable_if< traits::is_tensorT< T >, void >::type
463  localIndex const index,
464  integer const component,
465  real64 const value )
466  {
467  if( component >= 0 )
468  {
469  for( localIndex a = 0; a < field.size( 1 ); ++a )
470  {
471  for( localIndex b = 0; b < field.size( 2 ); ++b )
472  {
473  for( localIndex c = 0; c < field.size( 3 ); ++c )
474  {
475  OP::template apply( field( index, a, b, c )[component], value );
476  }
477  }
478  }
479  }
480  else
481  {
482  for( localIndex a = 0; a < field.size( 1 ); ++a )
483  {
484  for( localIndex b = 0; b < field.size( 2 ); ++b )
485  {
486  for( localIndex c = 0; c < field.size( 3 ); ++c )
487  {
488  for( localIndex d = 0; d < T::size(); ++d )
489  {
490  OP::template apply( field( index, a, b, c )[d], value );
491  }
492  }
493  }
494  }
495  }
496  }
497 
507  template< typename T, int USD >
509  static inline void
511  localIndex const index,
512  integer const component,
513  real64 & value )
514  {
515  GEOS_UNUSED_VAR( field );
516  GEOS_UNUSED_VAR( index );
517  GEOS_UNUSED_VAR( component );
518  GEOS_UNUSED_VAR( value );
519  GEOS_ERROR( "readFieldValue: unsupported operation" );
520  }
521 
522 };
523 
530 {
534 
554  static inline void
556  globalIndex const dofRankOffset,
558  real64 & rhs,
559  real64 const bcValue,
560  real64 const fieldValue )
561  {
562  globalIndex const localRow = dof - dofRankOffset;
563  if( localRow >= 0 && localRow < matrix.numRows() )
564  {
565  arraySlice1d< globalIndex const > const columns = matrix.getColumns( localRow );
566  arraySlice1d< real64 > const entries = matrix.getEntries( localRow );
567  localIndex const numEntries = matrix.numNonZeros( localRow );
568 
569  real64 diagonal = 0;
570  real64 const minDiagonal = 1e-15;
571  for( localIndex j = 0; j < numEntries; ++j )
572  {
573  if( columns[ j ] == dof )
574  {
575  // check that the entry is large enough to enforce the boundary condition
576  if( entries[j] >= 0 && entries[j] < minDiagonal )
577  {
578  entries[ j ] = minDiagonal;
579  }
580  else if( entries[j] < 0 && entries[j] > -minDiagonal )
581  {
582  entries[ j ] = -minDiagonal;
583  }
584  diagonal = entries[j];
585  }
586  else
587  { entries[ j ] = 0; }
588  }
589 
590  rhs = -diagonal * (bcValue - fieldValue);
591  }
592  else
593  {
594  rhs = 0.0;
595  }
596  }
597 
606  template< typename POLICY >
607  static inline void prescribeRhsValues( arrayView1d< real64 > const & rhs,
609  globalIndex const dofRankOffset,
610  arrayView1d< real64 const > const & values )
611  {
612  GEOS_ASSERT_EQ( dof.size(), values.size() );
613  forAll< POLICY >( dof.size(), [rhs, dof, dofRankOffset, values] GEOS_HOST_DEVICE ( localIndex const a )
614  {
615  globalIndex const localRow = dof[ a ] - dofRankOffset;
616  if( localRow >= 0 && localRow < rhs.size() )
617  { rhs[ localRow ] = values[ a ]; }
618  } );
619  }
620 };
621 
628 {
632 
644  static inline void
646  globalIndex const dofRankOffset,
648  real64 & rhs,
649  real64 const bcValue,
650  real64 const fieldValue )
651  {
652  GEOS_UNUSED_VAR( dof );
653  GEOS_UNUSED_VAR( dofRankOffset );
654  GEOS_UNUSED_VAR( matrix );
655  GEOS_UNUSED_VAR( fieldValue );
656  rhs += bcValue;
657  }
658 
667  template< typename POLICY >
668  static inline void prescribeRhsValues( arrayView1d< real64 > const & rhs,
670  globalIndex const dofRankOffset,
671  arrayView1d< real64 const > const & values )
672  {
673  GEOS_ASSERT_EQ( dof.size(), values.size() );
674  forAll< POLICY >( dof.size(), [rhs, dof, dofRankOffset, values] GEOS_HOST_DEVICE ( localIndex const a )
675  {
676  globalIndex const localRow = dof[ a ] - dofRankOffset;
677  if( localRow >= 0 && localRow < rhs.size() )
678  { rhs[ localRow ] += values[ a ]; }
679  } );
680  }
681 
682 };
683 
684 } //namespace geos
685 
686 #endif //GEOS_COMMON_FIELDSPECIFICATIONOPS_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
Definition: GeosxMacros.hpp:84
#define GEOS_ERROR(msg)
Raise a hard error and terminate the program.
Definition: Logger.hpp:157
#define GEOS_ASSERT(EXP)
Assert a condition in debug builds.
Definition: Logger.hpp:177
#define GEOS_ASSERT_EQ(lhs, rhs)
Assert that two values compare equal in debug builds.
Definition: Logger.hpp:410
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:180
LvArray::CRSMatrixView< T, COL_INDEX, localIndex const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
Definition: DataTypes.hpp:310
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
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
Definition: DataTypes.hpp:184
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:82
ArrayView< T, 4, USD > arrayView4d
Alias for 4D array view.
Definition: DataTypes.hpp:228
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:196
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Definition: DataTypes.hpp:212
static GEOS_HOST_DEVICE void SpecifyFieldValue(globalIndex const dof, globalIndex const dofRankOffset, CRSMatrixView< real64, globalIndex const > const &matrix, real64 &rhs, real64 const bcValue, real64 const fieldValue)
Function to apply a value to a vector field for a single dof.
static void prescribeRhsValues(arrayView1d< real64 > const &rhs, arrayView1d< globalIndex const > const &dof, globalIndex const dofRankOffset, arrayView1d< real64 const > const &values)
Function to add some values of a vector.
static void prescribeRhsValues(arrayView1d< real64 > const &rhs, arrayView1d< globalIndex const > const &dof, globalIndex const dofRankOffset, arrayView1d< real64 const > const &values)
Function to add some values of a vector.
static GEOS_HOST_DEVICE void SpecifyFieldValue(globalIndex const dof, globalIndex const dofRankOffset, CRSMatrixView< real64, globalIndex const > const &matrix, real64 &rhs, real64 const bcValue, real64 const fieldValue)
Function to apply a Dirichlet like boundary condition to a single dof in a system of equations.
OP OpType
Alias for OP, the operator.
static GEOS_HOST_DEVICE void readFieldValue(arrayView3d< T const, USD > const &field, localIndex const index, integer const component, real64 &value)
This function is not meaningful. It exists for generic purposes, but will result in an error if calle...
static GEOS_HOST_DEVICE std::enable_if< !traits::is_tensorT< T >, void >::type SpecifyFieldValue(arrayView1d< T > const &field, localIndex const index, integer const component, real64 const value)
Pointwise application of a value to a field.
static GEOS_HOST_DEVICE std::enable_if< traits::is_tensorT< T >, void >::type SpecifyFieldValue(arrayView1d< T > const &field, localIndex const index, integer const component, real64 const value)
Pointwise application of value to a field variable.
static GEOS_HOST_DEVICE std::enable_if< !traits::is_tensorT< T >, void >::type readFieldValue(arrayView2d< T const, USD > const &field, localIndex const index, integer const component, real64 &value)
Read value from a 2d field.
static GEOS_HOST_DEVICE void readFieldValue(arrayView4d< T const, USD > const &field, localIndex const index, integer const component, real64 &value)
This function is not meaningful. It exists for generic purposes, but will result in an error if calle...
static GEOS_HOST_DEVICE std::enable_if< traits::is_tensorT< T >, void >::type readFieldValue(arrayView2d< T const, USD > const &field, localIndex const index, integer const component, real64 &value)
This function is not meaningful. It exists for generic purposes, but will result in an error if calle...
static GEOS_HOST_DEVICE std::enable_if< !traits::is_tensorT< T >, void >::type SpecifyFieldValue(arrayView3d< T, USD > const &field, localIndex const index, integer const component, real64 const value)
Pointwise application of a value to a field variable.
static GEOS_HOST_DEVICE std::enable_if< traits::is_tensorT< T >, void >::type SpecifyFieldValue(arrayView2d< T, USD > const &field, localIndex const index, integer const component, real64 const value)
Pointwise application of a value to a field variable.
static GEOS_HOST_DEVICE std::enable_if< !traits::is_tensorT< T >, void >::type SpecifyFieldValue(arrayView4d< T, USD > const &field, localIndex const index, integer const component, real64 const value)
Pointwise application of a value to a field variable.
static GEOS_HOST_DEVICE std::enable_if< traits::is_tensorT< T >, void >::type SpecifyFieldValue(arrayView3d< T, USD > const &field, localIndex const index, integer const component, real64 const value)
Pointwise application of a value to a field variable.
static GEOS_HOST_DEVICE std::enable_if< traits::is_tensorT< T >, void >::type readFieldValue(arrayView1d< T const > const &field, localIndex const index, integer const component, real64 &value)
Read a field value.
static GEOS_HOST_DEVICE std::enable_if< !traits::is_tensorT< T >, void >::type readFieldValue(arrayView1d< T const > const &field, localIndex const index, integer const component, real64 &value)
Read a field value.
static GEOS_HOST_DEVICE std::enable_if< !traits::is_tensorT< T >, void >::type SpecifyFieldValue(arrayView2d< T, USD > const &field, localIndex const index, integer const component, real64 const value)
Pointwise application of a value to a field variable.
static GEOS_HOST_DEVICE std::enable_if< traits::is_tensorT< T >, void >::type SpecifyFieldValue(arrayView4d< T, USD > const &field, localIndex const index, integer const component, real64 const value)
Pointwise application of a value to a field variable.
OpAdd Operator that adds a value.
static GEOS_HOST_DEVICE void apply(T &lhs, U const &rhs)
Pointwise update of a value.
OpEqual Operator that sets a value.
static GEOS_HOST_DEVICE void apply(T &lhs, U const &rhs)
Pointwise set of a value.