GEOSX
FieldSpecificationOps.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University
7  * Copyright (c) 2018-2020 TotalEnergies
8  * Copyright (c) 2019- GEOSX Contributors
9  * All rights reserved
10  *
11  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
12  * ------------------------------------------------------------------------------------------------------------
13  */
14 
19 #ifndef GEOS_COMMON_FIELDSPECIFICATIONOPS_HPP
20 #define GEOS_COMMON_FIELDSPECIFICATIONOPS_HPP
21 
22 #include "codingUtilities/traits.hpp"
23 #include "common/DataTypes.hpp"
24 #include "common/GEOS_RAJA_Interface.hpp"
25 
26 namespace geos
27 {
28 
32 struct OpEqual
33 {
41  template< typename T, typename U >
42  GEOS_HOST_DEVICE static inline
43  void apply( T & lhs, U const & rhs )
44  {
45  lhs = static_cast< T >( rhs );
46  }
47 };
48 
52 struct OpAdd
53 {
61  template< typename T, typename U >
62  GEOS_HOST_DEVICE static inline
63  void apply( T & lhs, U const & rhs )
64  {
65  lhs += static_cast< T >( rhs );
66  }
67 };
68 
72 template< typename OP >
74 {
76  using OpType = OP;
77 
89  template< typename T >
91  static inline typename std::enable_if< !traits::is_tensorT< T >, void >::type
93  localIndex const index,
94  integer const component,
95  real64 const value )
96  {
97  GEOS_UNUSED_VAR( component );
98  OP::template apply( field( index ), value );
99  }
100 
113  template< typename T >
115  static inline typename std::enable_if< traits::is_tensorT< T >, void >::type
117  localIndex const index,
118  integer const component,
119  real64 const value )
120  {
121  OP::template apply( field( index )[component], value );
122  }
123 
135  template< typename T >
137  static inline typename std::enable_if< !traits::is_tensorT< T >, void >::type
139  localIndex const index,
140  integer const component,
141  real64 & value )
142  {
143  GEOS_UNUSED_VAR( component );
144  OP::template apply( value, field( index ) );
145  }
146 
158  template< typename T >
160  static inline typename std::enable_if< traits::is_tensorT< T >, void >::type
162  localIndex const index,
163  integer const component,
164  real64 & value )
165  {
166  OP::template apply( value, field( index )[component] );
167  }
168 
181  template< typename T, int USD >
183  static inline typename std::enable_if< !traits::is_tensorT< T >, void >::type
185  localIndex const index,
186  integer const component,
187  real64 const value )
188  {
189  if( component >= 0 )
190  {
191  OP::template apply( field( index, component ), value );
192  }
193  else
194  {
195  for( localIndex a = 0; a < field.size( 1 ); ++a )
196  {
197  OP::template apply( field( index, a ), value );
198  }
199  }
200  }
201 
215  template< typename T, int USD >
217  static inline typename std::enable_if< traits::is_tensorT< T >, void >::type
219  localIndex const index,
220  integer const component,
221  real64 const value )
222  {
223  if( component >= 0 )
224  {
225  for( localIndex a = 0; a < field.size( 1 ); ++a )
226  {
227  OP::template apply( field( index, a )[component], value );
228  }
229  }
230  else
231  {
232  for( localIndex a = 0; a < field.size( 1 ); ++a )
233  {
234  for( localIndex c = 0; c < T::SIZE; ++c )
235  {
236  OP::template apply( field( index, a )[c], value );
237  }
238  }
239  }
240  }
241 
254  template< typename T, int USD >
256  static inline typename std::enable_if< !traits::is_tensorT< T >, void >::type
258  localIndex const index,
259  integer const component,
260  real64 & value )
261  {
262  GEOS_ASSERT( component >= 0 );
263  OP::template apply( value, field( index, component ) );
264  }
265 
276  template< typename T, int USD >
278  static inline typename std::enable_if< traits::is_tensorT< T >, void >::type
280  localIndex const index,
281  integer const component,
282  real64 & value )
283  {
284  GEOS_UNUSED_VAR( field );
285  GEOS_UNUSED_VAR( index );
286  GEOS_UNUSED_VAR( component );
287  GEOS_UNUSED_VAR( value );
288  GEOS_ERROR( "readFieldValue: unsupported operation" );
289  }
290 
303  template< typename T, int USD >
305  static inline typename std::enable_if< !traits::is_tensorT< T >, void >::type
307  localIndex const index,
308  integer const component,
309  real64 const value )
310  {
311  if( component >= 0 )
312  {
313  for( localIndex a = 0; a < field.size( 1 ); ++a )
314  {
315  OP::template apply( field( index, a, component ), value );
316  }
317  }
318  else
319  {
320  for( localIndex a = 0; a < field.size( 1 ); ++a )
321  {
322  for( localIndex b = 0; b < field.size( 2 ); ++b )
323  {
324  OP::template apply( field( index, a, b ), value );
325  }
326  }
327  }
328  }
329 
343  template< typename T, int USD >
345  static inline typename std::enable_if< traits::is_tensorT< T >, void >::type
347  localIndex const index,
348  integer const component,
349  real64 const value )
350  {
351  if( component >= 0 )
352  {
353  for( localIndex a = 0; a < field.size( 1 ); ++a )
354  {
355  for( localIndex b = 0; b < field.size( 2 ); ++b )
356  {
357  OP::template apply( field( index, a, b )[component], value );
358  }
359  }
360  }
361  else
362  {
363  for( localIndex a = 0; a < field.size( 1 ); ++a )
364  {
365  for( localIndex b = 0; b < field.size( 2 ); ++b )
366  {
367  for( localIndex c = 0; c < T::size(); ++c )
368  {
369  OP::template apply( field( index, a, b )[c], value );
370  }
371  }
372  }
373  }
374  }
375 
385  template< typename T, int USD >
387  static inline void
389  localIndex const index,
390  integer const component,
391  real64 & value )
392  {
393  GEOS_UNUSED_VAR( field );
394  GEOS_UNUSED_VAR( index );
395  GEOS_UNUSED_VAR( component );
396  GEOS_UNUSED_VAR( value );
397  GEOS_ERROR( "readFieldValue: unsupported operation" );
398  }
399 
412  template< typename T, int USD >
414  static inline typename std::enable_if< !traits::is_tensorT< T >, void >::type
416  localIndex const index,
417  integer const component,
418  real64 const value )
419  {
420  if( component >= 0 )
421  {
422  for( localIndex a = 0; a < field.size( 1 ); ++a )
423  {
424  for( localIndex b = 0; b < field.size( 2 ); ++b )
425  {
426  OP::template apply( field( index, a, b, component ), value );
427  }
428  }
429  }
430  else
431  {
432  for( localIndex a = 0; a < field.size( 1 ); ++a )
433  {
434  for( localIndex b = 0; b < field.size( 2 ); ++b )
435  {
436  for( localIndex c = 0; c < field.size( 3 ); ++c )
437  {
438  OP::template apply( field( index, a, b, c ), value );
439  }
440  }
441  }
442  }
443  }
444 
458  template< typename T, int USD >
460  static inline typename std::enable_if< traits::is_tensorT< T >, void >::type
462  localIndex const index,
463  integer const component,
464  real64 const value )
465  {
466  if( component >= 0 )
467  {
468  for( localIndex a = 0; a < field.size( 1 ); ++a )
469  {
470  for( localIndex b = 0; b < field.size( 2 ); ++b )
471  {
472  for( localIndex c = 0; c < field.size( 3 ); ++c )
473  {
474  OP::template apply( field( index, a, b, c )[component], value );
475  }
476  }
477  }
478  }
479  else
480  {
481  for( localIndex a = 0; a < field.size( 1 ); ++a )
482  {
483  for( localIndex b = 0; b < field.size( 2 ); ++b )
484  {
485  for( localIndex c = 0; c < field.size( 3 ); ++c )
486  {
487  for( localIndex d = 0; d < T::size(); ++d )
488  {
489  OP::template apply( field( index, a, b, c )[d], value );
490  }
491  }
492  }
493  }
494  }
495  }
496 
506  template< typename T, int USD >
508  static inline void
510  localIndex const index,
511  integer const component,
512  real64 & value )
513  {
514  GEOS_UNUSED_VAR( field );
515  GEOS_UNUSED_VAR( index );
516  GEOS_UNUSED_VAR( component );
517  GEOS_UNUSED_VAR( value );
518  GEOS_ERROR( "readFieldValue: unsupported operation" );
519  }
520 
521 };
522 
529 {
533 
553  static inline void
555  globalIndex const dofRankOffset,
557  real64 & rhs,
558  real64 const bcValue,
559  real64 const fieldValue )
560  {
561  globalIndex const localRow = dof - dofRankOffset;
562  if( localRow >= 0 && localRow < matrix.numRows() )
563  {
564  arraySlice1d< globalIndex const > const columns = matrix.getColumns( localRow );
565  arraySlice1d< real64 > const entries = matrix.getEntries( localRow );
566  localIndex const numEntries = matrix.numNonZeros( localRow );
567 
568  real64 diagonal = 0;
569  real64 const minDiagonal = 1e-15;
570  for( localIndex j = 0; j < numEntries; ++j )
571  {
572  if( columns[ j ] == dof )
573  {
574  // check that the entry is large enough to enforce the boundary condition
575  if( entries[j] >= 0 && entries[j] < minDiagonal )
576  {
577  entries[ j ] = minDiagonal;
578  }
579  else if( entries[j] < 0 && entries[j] > -minDiagonal )
580  {
581  entries[ j ] = -minDiagonal;
582  }
583  diagonal = entries[j];
584  }
585  else
586  { entries[ j ] = 0; }
587  }
588 
589  rhs = -diagonal * (bcValue - fieldValue);
590  }
591  else
592  {
593  rhs = 0.0;
594  }
595  }
596 
605  template< typename POLICY >
606  static inline void prescribeRhsValues( arrayView1d< real64 > const & rhs,
608  globalIndex const dofRankOffset,
609  arrayView1d< real64 const > const & values )
610  {
611  GEOS_ASSERT_EQ( dof.size(), values.size() );
612  forAll< POLICY >( dof.size(), [rhs, dof, dofRankOffset, values] GEOS_HOST_DEVICE ( localIndex const a )
613  {
614  globalIndex const localRow = dof[ a ] - dofRankOffset;
615  if( localRow >= 0 && localRow < rhs.size() )
616  { rhs[ localRow ] = values[ a ]; }
617  } );
618  }
619 };
620 
627 {
631 
643  static inline void
645  globalIndex const dofRankOffset,
647  real64 & rhs,
648  real64 const bcValue,
649  real64 const fieldValue )
650  {
651  GEOS_UNUSED_VAR( dof );
652  GEOS_UNUSED_VAR( dofRankOffset );
653  GEOS_UNUSED_VAR( matrix );
654  GEOS_UNUSED_VAR( fieldValue );
655  rhs += bcValue;
656  }
657 
666  template< typename POLICY >
667  static inline void prescribeRhsValues( arrayView1d< real64 > const & rhs,
669  globalIndex const dofRankOffset,
670  arrayView1d< real64 const > const & values )
671  {
672  GEOS_ASSERT_EQ( dof.size(), values.size() );
673  forAll< POLICY >( dof.size(), [rhs, dof, dofRankOffset, values] GEOS_HOST_DEVICE ( localIndex const a )
674  {
675  globalIndex const localRow = dof[ a ] - dofRankOffset;
676  if( localRow >= 0 && localRow < rhs.size() )
677  { rhs[ localRow ] += values[ a ]; }
678  } );
679  }
680 
681 };
682 
683 } //namespace geos
684 
685 #endif //GEOS_COMMON_FIELDSPECIFICATIONOPS_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:48
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
Definition: GeosxMacros.hpp:83
#define GEOS_ERROR(msg)
Raise a hard error and terminate the program.
Definition: Logger.hpp:122
#define GEOS_ASSERT(EXP)
Assert a condition in debug builds.
Definition: Logger.hpp:142
#define GEOS_ASSERT_EQ(lhs, rhs)
Assert that two values compare equal in debug builds.
Definition: Logger.hpp:375
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:220
LvArray::CRSMatrixView< T, COL_INDEX, localIndex const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
Definition: DataTypes.hpp:350
double real64
64-bit floating point type.
Definition: DataTypes.hpp:139
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
Definition: DataTypes.hpp:224
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:122
GEOSX_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:128
ArrayView< T, 4, USD > arrayView4d
Alias for 4D array view.
Definition: DataTypes.hpp:268
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:236
GEOSX_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Definition: DataTypes.hpp:252
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.