GEOS
Wrapper.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_DATAREPOSITORY_WRAPPER_HPP_
21 #define GEOS_DATAREPOSITORY_WRAPPER_HPP_
22 
23 // Source inclues
24 #include "wrapperHelpers.hpp"
25 #include "KeyNames.hpp"
26 #include "LvArray/src/limits.hpp"
27 #include "common/DataTypes.hpp"
28 #include "codingUtilities/SFINAE_Macros.hpp"
29 #include "LvArray/src/Macros.hpp"
30 #include "BufferOps.hpp"
31 #include "BufferOpsDevice.hpp"
32 #include "RestartFlags.hpp"
33 #include "codingUtilities/traits.hpp"
34 #include "common/GeosxConfig.hpp"
35 #include "DefaultValue.hpp"
36 #include "LvArray/src/system.hpp"
37 #include "WrapperBase.hpp"
38 
39 // System includes
40 #include <cstdlib>
41 #include <type_traits>
42 
43 namespace geos
44 {
45 
46 namespace dataRepository
47 {
48 //template< typename U >
49 //static void totalViewType( char * const dataType );
50 
51 using namespace wrapperLimits;
52 
57 template< typename T >
58 class Wrapper final : public WrapperBase
59 {
60 public:
61 
65  using TYPE = T;
66 
71 
77  explicit Wrapper( string const & name,
78  Group & parent ):
79  WrapperBase( name, parent, rtTypes::getTypeName( typeid( T ) ) ),
80  m_ownsData( true ),
81  m_isClone( false ),
82  m_data( new T() ),
83  m_default()
84  {
85  if( traits::is_tensorT< T > || std::is_arithmetic< T >::value || traits::is_string< T > )
86  {
87  setSizedFromParent( 0 );
88  }
89 
90  setName();
91  }
92 
99  explicit Wrapper( string const & name,
100  Group & parent,
101  std::unique_ptr< T > object ):
102  WrapperBase( name, parent, rtTypes::getTypeName( typeid( T ) ) ),
103  m_ownsData( true ),
104  m_isClone( false ),
105  m_data( object.release() ),
106  m_default()
107  {
108  if( traits::is_tensorT< T > || std::is_arithmetic< T >::value || traits::is_string< T > )
109  {
110  setSizedFromParent( 0 );
111  }
112 
113  setName();
114  }
115 
122  explicit Wrapper( string const & name,
123  Group & parent,
124  T * object ):
125  WrapperBase( name, parent, rtTypes::getTypeName( typeid( T ) ) ),
126  m_ownsData( false ),
127  m_isClone( false ),
128  m_data( object ),
129  m_default()
130  {
131  if( traits::is_tensorT< T > || std::is_arithmetic< T >::value || traits::is_string< T > )
132  {
133  setSizedFromParent( 0 );
134  }
135 
136  setName();
137  }
138 
144  virtual ~Wrapper() noexcept override
145  {
146  if( m_ownsData )
147  {
148  delete m_data;
149  }
150  //tvTemplateInstantiation();
151  }
152 
159  Wrapper & operator=( Wrapper const & source )
160  {
161  m_data = source.m_data;
162  return *this;
163  }
164 
170  Wrapper & operator=( Wrapper && source )
171  {
172  m_data = std::move( source.m_data );
173  return *this;
174  }
175 
177 
182 
184  virtual std::unique_ptr< WrapperBase > clone( string const & name,
185  Group & parent ) override
186  {
187  std::unique_ptr< Wrapper< T > > clonedWrapper = std::make_unique< Wrapper< T > >( name, parent, m_data );
188  clonedWrapper->copyWrapperAttributes( *this );
189  clonedWrapper->m_isClone = true;
190  return clonedWrapper;
191  }
192 
193  virtual void copyWrapper( WrapperBase const & source ) override
194  {
195  GEOS_ERROR_IF( source.getName() != m_name, "Tried to copy wrapper with a different name" );
196  copyWrapperAttributes( source );
197  copyData( source );
198  }
199 
201  virtual void copyWrapperAttributes( WrapperBase const & source ) override
202  {
204  Wrapper< T > const & castedSource = dynamicCast< Wrapper< T > const & >( source );
205  m_ownsData = castedSource.m_ownsData;
206  m_default = castedSource.m_default;
207  m_dimLabels = castedSource.m_dimLabels;
208  m_limits = castedSource.m_limits;
209  }
210 
212  virtual const std::type_info & getTypeId() const noexcept override
213  {
214  return typeid(T);
215  }
216 
223  static Wrapper & cast( WrapperBase & wrapper )
224  {
225  GEOS_ERROR_IF( wrapper.getTypeId() != typeid( T ),
226  GEOS_FMT( "Invalid downcast to Wrapper< {} >", LvArray::system::demangleType< T >() ) );
227  return static_cast< Wrapper< T > & >( wrapper );
228  }
229 
236  static Wrapper< T > const & cast( WrapperBase const & wrapper )
237  {
238  GEOS_ERROR_IF( wrapper.getTypeId() != typeid( T ),
239  GEOS_FMT( "Invalid downcast to Wrapper< {} >", LvArray::system::demangleType< T >() ) );
240  return static_cast< Wrapper< T > const & >( wrapper );
241  }
242 
244 
245  virtual int numArrayDims() const override
246  {
247  return wrapperHelpers::numArrayDims( reference() );
248  }
249 
250  virtual localIndex numArrayComp() const override
251  {
252  return wrapperHelpers::numArrayComp( reference() );
253  }
254 
255  virtual Wrapper & setDimLabels( integer const dim, Span< string const > const labels ) override
256  {
257  m_dimLabels.set( dim, labels );
258  return *this;
259  }
260 
261  virtual Span< string const > getDimLabels( integer const dim ) const override
262  {
263  return m_dimLabels.get( dim );
264  }
265 
267 
269  virtual
270  HistoryMetadata getHistoryMetadata( localIndex const packCount = -1 ) const override final
271  {
272  return geos::getHistoryMetadata( getName(), referenceAsView( ), numArrayComp(), packCount );
273  }
274 
279 
282  virtual
283  bool isPackable( bool onDevice ) const override
284  {
285  if( onDevice )
286  {
287  // this isn't accurate if array/arraview return false for this, which I think they do
288  return bufferOps::can_memcpy< T >;
289  }
290  else
291  {
292  return bufferOps::is_packable< T >;
293  }
294  }
295 
298  virtual
299  localIndex unpack( buffer_unit_type const * & buffer, bool withMetadata, bool onDevice, parallelDeviceEvents & events ) override final
300  {
301  localIndex unpackedSize = 0;
302  if( withMetadata )
303  {
304  string name;
305  unpackedSize += bufferOps::Unpack( buffer, name );
306  GEOS_ERROR_IF( name != getName(), "buffer unpack leads to wrapper names that don't match" );
307  }
308  if( onDevice )
309  {
310  if( withMetadata )
311  {
312  unpackedSize += wrapperHelpers::UnpackDevice( buffer, referenceAsView(), events );
313  }
314  else
315  {
316  unpackedSize += wrapperHelpers::UnpackDataDevice( buffer, referenceAsView(), events );
317  }
318  }
319  else
320  {
321  unpackedSize += bufferOps::Unpack( buffer, *m_data );
322  }
323  return unpackedSize;
324  }
325 
328  virtual
330  arrayView1d< localIndex const > const & unpackIndices,
331  bool withMetadata,
332  bool onDevice,
333  parallelDeviceEvents & events,
334  MPI_Op op ) override final
335  {
336  localIndex unpackedSize = 0;
337 
338  if( withMetadata )
339  {
340  string name;
341  unpackedSize += bufferOps::Unpack( buffer, name );
342  GEOS_ERROR_IF( name != getName(), "buffer unpack leads to wrapper names that don't match" );
343  }
344  if( onDevice )
345  {
346  if( withMetadata )
347  {
348  unpackedSize += wrapperHelpers::UnpackByIndexDevice( buffer, referenceAsView(), unpackIndices, events, op );
349  }
350  else
351  {
352  unpackedSize += wrapperHelpers::UnpackDataByIndexDevice( buffer, referenceAsView(), unpackIndices, events, op );
353  }
354  }
355  else
356  {
357  unpackedSize += wrapperHelpers::UnpackByIndex( buffer, *m_data, unpackIndices );
358  }
359 
360  return unpackedSize;
361  }
362 
364 
366  void const * voidPointer() const override
367  { return wrapperHelpers::dataPtr( *m_data ); }
368 
370  virtual localIndex elementByteSize() const override
371  { return wrapperHelpers::byteSizeOfElement< T >(); }
372 
373  virtual size_t bytesAllocated() const override final
374  {
375  return m_isClone ? 0 : wrapperHelpers::byteSize< T >( *m_data );
376  }
377 
378 
386 
388  virtual localIndex size() const override
389  { return wrapperHelpers::size( *m_data ); }
390 
392  virtual void resize( int ndims, localIndex const * const dims ) override
393  {
394  wrapperHelpers::move( *m_data, hostMemorySpace, true );
395  wrapperHelpers::resizeDimensions( *m_data, ndims, dims );
396  }
397 
399  virtual void reserve( localIndex const newCapacity ) override
400  {
401  wrapperHelpers::move( *m_data, hostMemorySpace, true );
402  wrapperHelpers::reserve( reference(), newCapacity );
403  }
404 
406  virtual localIndex capacity() const override
407  {
408  // We don't use reference() here because that would return an ArrayView which has no capacity method.
409  return wrapperHelpers::capacity( *m_data );
410  }
411 
413  virtual void resize( localIndex const newSize ) override
414  {
415  wrapperHelpers::move( *m_data, hostMemorySpace, true );
416  if constexpr ( traits::HasMemberFunction_resizeDefault< T > && DefaultValue< T >::has_default_value )
417  {
418  wrapperHelpers::resizeDefault( reference(), newSize, m_default, this->getName() );
419  }
420  else
421  {
422  wrapperHelpers::resize( reference(), newSize );
423  }
424  }
425 
427  struct copy_wrapper
428  {
429  template< typename U, int NDIM, typename PERMUTATION >
430  static void copy( Array< U, NDIM, PERMUTATION > const & array, localIndex const sourceIndex, localIndex const destIndex )
431  {
432  LvArray::forValuesInSliceWithIndices( array[ sourceIndex ],
433  [destIndex, &array]( U const & sourceVal, auto const ... indicesToErase )
434  {
435  array( destIndex, indicesToErase ... ) = sourceVal;
436  } );
437  }
438 
439  template< typename U >
440  static void copy( U const &, localIndex const, localIndex const )
441  {}
442 
443  template< typename U=T >
444  static std::enable_if_t< traits::hasCopyAssignmentOp< U > >
445  copyData( U & destinationData, U const & sourceData )
446  {
447  destinationData = sourceData;
448  }
449 
450  template< typename U=T >
451  static std::enable_if_t< !traits::hasCopyAssignmentOp< U > >
452  copyData( U &, U const & )
453  {}
454  };
456 
458  virtual void copy( localIndex const sourceIndex, localIndex const destIndex ) override
459  {
460  copy_wrapper::copy( reference(), sourceIndex, destIndex );
461  }
462 
463 
464 
465  virtual void copyData( WrapperBase const & source ) override
466  {
467  Wrapper< T > const & castedSource = dynamicCast< Wrapper< T > const & >( source );
468  copy_wrapper::copyData( *m_data, *castedSource.m_data );
469  }
470 
471 
473  struct erase_wrapper // This should probably be in LvArray?
474  {
475  template< typename TYPE >
476  static void erase( TYPE &, std::set< localIndex > const & )
477  {}
478 
479  template< typename TYPE >
480  static void erase( array1d< TYPE > & array, std::set< localIndex > const & indicesToErase )
481  {
482  int oldSize = array.size( 0 );
483  int numToErase = indicesToErase.size();
484  int newSize = oldSize - numToErase;
485  std::set< localIndex >::iterator it = indicesToErase.begin();
486  int offset = 0;
487  for( localIndex i=*it+1; i<oldSize; i++ )
488  {
489  if( i == *it + 1 )
490  {
491  offset++;
492  if( offset < numToErase )
493  {
494  it++;
495  }
496  }
497  array[i-offset] = array[i];
498  }
499  array.resize( newSize );
500  }
501 
502  template< typename TYPE >
503  static void erase( array2d< TYPE > & array, std::set< localIndex > const & indicesToErase )
504  {
505  int oldSize = array.size( 0 );
506  int numToErase = indicesToErase.size();
507  int newSize = oldSize - numToErase;
508  int dim1 = array.size( 1 );
509  std::set< localIndex >::iterator it = indicesToErase.begin();
510  int offset = 0;
511  for( localIndex i=*it+1; i<oldSize; i++ )
512  {
513  if( i == *it + 1 )
514  {
515  offset++;
516  if( offset < numToErase )
517  {
518  it++;
519  }
520  }
521  for( int j=0; j<dim1; j++ )
522  {
523  array[i-offset][j] = array[i][j];
524  }
525  }
526  array.resize( newSize );
527  }
528 
529  template< typename TYPE >
530  static void erase( array3d< TYPE > & array, std::set< localIndex > const & indicesToErase )
531  {
532  int oldSize = array.size( 0 );
533  int numToErase = indicesToErase.size();
534  int newSize = oldSize - numToErase;
535  int dim1 = array.size( 1 );
536  int dim2 = array.size( 2 );
537  std::set< localIndex >::iterator it = indicesToErase.begin();
538  int offset = 0;
539  for( localIndex i=*it+1; i<oldSize; i++ )
540  {
541  if( i == *it + 1 )
542  {
543  offset++;
544  if( offset < numToErase )
545  {
546  it++;
547  }
548  }
549  for( int j=0; j<dim1; j++ )
550  {
551  for( int k=0; k<dim2; k++ )
552  {
553  array[i-offset][j][k] = array[i][j][k];
554  }
555  }
556  }
557  array.resize( newSize );
558  }
559  };
561 
562 
564  void erase( std::set< localIndex > const & indicesToErase ) override
565  {
566  GEOS_ERROR_IF( indicesToErase.size() == 0, "Wrapper::erase() can only be called on a populated set of indices!" );
567  erase_wrapper::erase( reference(), indicesToErase );
568  }
569 
570 
572  virtual void move( LvArray::MemorySpace const space, bool const touch ) const override
573  { return wrapperHelpers::move( *m_data, space, touch ); }
574 
576  virtual Regex const & getTypeRegex() const override
577  { return rtTypes::getTypeRegex< T >( m_rtTypeName ); }
578 
580 
585 
590  T & reference()
591  { return *m_data; }
592 
599  { return referenceAsView(); }
600 
609  template< typename _T=T, typename=std::enable_if_t< traits::HasMemberFunction_toView< _T > > >
611  { return m_data->toView(); }
612 
616  template< typename _T=T, typename=std::enable_if_t< !traits::HasMemberFunction_toView< _T > > >
618  { return *m_data; }
619 
623  template< typename _T=T, typename=std::enable_if_t< traits::HasMemberFunction_toView< _T > > >
625  { return m_data->toViewConst(); }
626 
630  template< typename _T=T, typename=std::enable_if_t< !traits::HasMemberFunction_toView< _T > > >
631  T const & referenceAsView() const
632  { return *m_data; }
633 
635 
640 
644  virtual bool hasDefaultValue() const final override
645  {
646  return m_default.has_default_value;
647  }
648 
653  template< typename U=T >
654  DefaultValue< T > const &
656  {
657  return m_default;
658  }
659 
660 
665  template< typename U=T >
666  std::enable_if_t< DefaultValue< U >::has_default_value, typename DefaultValue< U >::value_type const & >
668  {
669  return m_default.value;
670  }
671 
677  template< typename U=T >
678  std::enable_if_t< DefaultValue< U >::has_default_value, Wrapper< T > & >
679  setDefaultValue( typename DefaultValue< U >::value_type const & defaultVal )
680  {
681  m_default.value = defaultVal;
682  return *this;
683  }
684 
690  template< typename U=T >
691  std::enable_if_t< !traits::is_array< U > && DefaultValue< U >::has_default_value, Wrapper< T > & >
692  setApplyDefaultValue( typename DefaultValue< U >::value_type const & defaultVal )
693  {
694  m_default.value = defaultVal;
695  *m_data = m_default.value;
696  return *this;
697  }
698 
704  template< typename U=T >
705  std::enable_if_t< traits::is_array< U > && DefaultValue< U >::has_default_value, Wrapper< T > & >
706  setApplyDefaultValue( typename DefaultValue< U >::value_type const & defaultVal )
707  {
708  m_default.value = defaultVal;
709  m_data->template setValues< serialPolicy >( m_default.value );
710  return *this;
711  }
712 
716  virtual string getDefaultValueString() const override
717  {
718  std::ostringstream ss;
719  ss << std::string( numArrayDims(), '{' ) << m_default << std::string( numArrayDims(), '}' );
720  return ss.str();
721  }
722 
741  template< typename U=T >
742  std::enable_if_t< is_limitable_v< U >, Wrapper< T > & >
743  setLimits( std::optional< LimitArg< limit_value_type_t< T > > > min,
744  std::optional< LimitArg< limit_value_type_t< T > > > max,
745  LimitsMode mode = LimitsMode::Error )
746  {
747  using LimitT = limit_value_type_t< T >;
748  std::optional< Bound< LimitT > > const minBound = toBound< LimitT >( min );
749  std::optional< Bound< LimitT > > const maxBound = toBound< LimitT >( max );
750  if( minBound.has_value() && maxBound.has_value() )
751  {
752  GEOS_ASSERT_LE_MSG( minBound.value(), maxBound.value(),
753  "Min value should be less or equal to max value." );
754  }
755  m_limits.min = minBound;
756  m_limits.max = maxBound;
757  m_limitsMode = mode;
758  return *this;
759  }
760 
761  template< typename U=T >
762  std::enable_if_t< !is_limitable_v< U > && !traits::is_array_type< U >, Wrapper< T > & >
763  setLimits( std::optional< LimitArg< limit_value_type_t< T > > >,
764  std::optional< LimitArg< limit_value_type_t< T > > >,
765  LimitsMode GEOS_UNUSED_PARAM( mode ) )
766  {
767  static_assert( is_limitable_v< U >,
768  "setLimits is only supported on scalar arithmetic types." );
769  return *this;
770  }
771 
777  template< typename U=T >
778  std::enable_if_t< is_limitable_v< U >, std::optional< Bound< limit_value_type_t< T > > > const & >
779  getMinBound() const
780  {
781  return m_limits.min;
782  }
783 
789  template< typename U=T >
790  std::enable_if_t< is_limitable_v< U >, std::optional< Bound< limit_value_type_t< T > > > const & >
791  getMaxBound() const
792  {
793  return m_limits.max;
794  }
795 
799  virtual string getLimitsString() const override
800  {
801  return getLimitsStringImpl();
802  }
803 
804  template< typename U=T >
805  std::enable_if_t< is_limitable_v< U >, string >
806  getLimitsStringImpl() const
807  {
808  return m_limits.getRangeStr();
809  }
810 
811  template< typename U=T >
812  std::enable_if_t< !is_limitable_v< U >, string >
813  getLimitsStringImpl() const
814  {
815  return string();
816  }
817 
818  template< typename U=T >
819  std::enable_if_t< is_limitable_v< U > && !traits::is_array_type< U >, void >
820  validateLimits()
821  {
822  if( (!m_limits.min.has_value() && !m_limits.max.has_value()) ||
823  m_limitsMode == LimitsMode::Indicative )
824  {
825  return;
826  }
827  validateLimitValue( reference() );
828  }
829 
830  template< typename U=T >
831  std::enable_if_t< is_limitable_v< U > && traits::is_array_type< U >, void >
832  validateLimits()
833  {
834  if( (!m_limits.min.has_value() && !m_limits.max.has_value()) ||
835  m_limitsMode == LimitsMode::Indicative )
836  {
837  return;
838  }
839  auto const values = m_data->toViewConst();
840  for( limit_value_type_t< T > value : values )
841  {
842  validateLimitValue( value );
843  }
844  }
845 
846  template< typename U=T >
847  std::enable_if_t< !is_limitable_v< U >, void >
848  validateLimits()
849  {
850  /* no-op */
851  }
852 
853 
854  virtual bool processInputFile( xmlWrapper::xmlNode const & targetNode,
855  xmlWrapper::xmlNodePos const & nodePos ) override
856  {
857  InputFlags const inputFlag = getInputFlag();
858  if( inputFlag >= InputFlags::OPTIONAL )
859  {
860  try
861  {
862  if( inputFlag == InputFlags::REQUIRED || !hasDefaultValue() )
863  {
864  m_successfulReadFromInput = xmlWrapper::readAttributeAsType( reference(),
865  getName(),
866  rtTypes::getTypeRegex< T >( getRTTypeName() ),
867  targetNode,
868  inputFlag == InputFlags::REQUIRED );
869  GEOS_THROW_IF( !m_successfulReadFromInput,
870  GEOS_FMT( "XML Node {} ({}) with name={} is missing required attribute '{}'.\n"
871  "For more details, please refer to documentation at:\n"
872  "http://geosx-geosx.readthedocs-hosted.com/en/latest/docs/sphinx/userGuide/Index.html",
873  targetNode.name(), nodePos.toString(), targetNode.attribute( "name" ).value(),
874  getName()),
875  InputError );
876  }
877  else
878  {
879  m_successfulReadFromInput = xmlWrapper::readAttributeAsType( reference(),
880  getName(),
881  rtTypes::getTypeRegex< T >( getRTTypeName() ),
882  targetNode,
883  getDefaultValueStruct() );
884  }
885 
886  if( m_successfulReadFromInput )
887  {
888  validateLimits();
889  }
890  }
891  catch( std::exception const & ex )
892  {
893  xmlWrapper::processInputException( ex, getName(), targetNode, nodePos );
894  }
895 
896  if( m_successfulReadFromInput )
897  createDataContext( targetNode, nodePos );
898 
899  return true;
900  }
901 
902  return false;
903  }
904 
906 
912  void setName()
913  { wrapperHelpers::setName( reference(), m_conduitNode.path() ); }
914 
915 
917  void addBlueprintField( conduit::Node & fields,
918  string const & name,
919  string const & topology,
920  stdVector< string > const & componentNames = {} ) const override
921  { wrapperHelpers::addBlueprintField( reference(), fields, name, topology, componentNames ); }
922 
924  void populateMCArray( conduit::Node & node, stdVector< string > const & componentNames = {} ) const override
925  { wrapperHelpers::populateMCArray( reference(), node, componentNames ); }
926 
928  std::unique_ptr< WrapperBase > averageOverSecondDim( string const & name, Group & group ) const override
929  {
930  auto ptr = wrapperHelpers::averageOverSecondDim( reference() );
931  using U = typename decltype( ptr )::element_type;
932 
933  GEOS_ERROR_IF( ptr == nullptr, "Failed to average over the second dimension of." );
934 
935  auto ret = std::make_unique< Wrapper< U > >( name, group, std::move( ptr ) );
936  for( integer dim = 2; dim < numArrayDims(); ++dim )
937  {
938  ret->setDimLabels( dim - 1, getDimLabels( dim ) );
939  }
940 
941  return ret;
942  }
943 
945  void registerToWrite() const override
946  {
947  m_conduitNode.reset();
948 
949  if( getRestartFlags() == RestartFlags::NO_WRITE )
950  {
951  return;
952  }
953 
954  move( hostMemorySpace, false );
955 
956  m_conduitNode[ "__sizedFromParent__" ].set( sizedFromParent() );
957 
958  wrapperHelpers::pushDataToConduitNode( *m_data, m_conduitNode );
959  }
960 
962  void finishWriting() const override
963  { m_conduitNode.reset(); }
964 
965 
967  bool loadFromConduit() override
968  {
969  if( getRestartFlags() != RestartFlags::WRITE_AND_READ )
970  {
971  m_conduitNode.reset();
972  return false;
973  }
974 
975  setSizedFromParent( m_conduitNode[ "__sizedFromParent__" ].value() );
976 
977  wrapperHelpers::pullDataFromConduitNode( *m_data, m_conduitNode );
978 
979  m_conduitNode.reset();
980 
981  return true;
982  }
983 
990 
991  /*
992  * @brief Set whether this wrapper is resized when its parent is resized.
993  * @param val an int that is converted into a bool
994  * @return a pointer to this wrapper
995  */
996 
1001  {
1003  return *this;
1004  }
1005 
1010  {
1012  return *this;
1013  }
1014 
1019  {
1020  WrapperBase::setPlotLevel( flag );
1021  return *this;
1022  }
1023 
1028  {
1029  WrapperBase::setInputFlag( input );
1030  return *this;
1031  }
1032 
1036  Wrapper< T > & setDescription( string const & description )
1037  {
1038  WrapperBase::setDescription( description );
1039  return *this;
1040  }
1041 
1045  Wrapper< T > & appendDescription( string const & description )
1046  {
1047  WrapperBase::appendDescription( description );
1048  return *this;
1049  }
1050 
1054  Wrapper< T > & setRegisteringObjects( string const & objectName )
1055  {
1056  WrapperBase::setRegisteringObjects( objectName );
1057  return *this;
1058  }
1059 
1064  {
1065  WrapperBase::setRTTypeName( rtTypeName );
1066  return *this;
1067  }
1068 
1070 
1071 #if defined(USE_TOTALVIEW_OUTPUT)
1072  virtual string totalviewTypeName() const override
1073  {
1074  return LvArray::system::demangle( typeid( Wrapper< T > ).name() );
1075  }
1076 
1077  virtual int setTotalviewDisplay() const override
1078  {
1079  //std::cout<<"executing Wrapper::setTotalviewDisplay()"<<std::endl;
1080  WrapperBase::setTotalviewDisplay();
1081  TV_ttf_add_row( "m_ownsData", "bool", &m_ownsData );
1082  TV_ttf_add_row( "m_data", LvArray::system::demangle< T >().c_str(), m_data );
1083  TV_ttf_add_row( "m_default", LvArray::system::demangle< DefaultValue< T > >().c_str(), &m_default );
1084  return 0;
1085  }
1086 // void tvTemplateInstantiation();
1087 #endif
1088 
1089 #if defined(GEOS_USE_PYGEOSX)
1090  virtual PyObject * createPythonObject( ) override
1091  { return wrapperHelpers::createPythonObject( reference() ); }
1092 #endif
1093 
1094 private:
1095 
1109  template< bool DO_PACKING >
1110  localIndex packImpl( buffer_unit_type * & buffer,
1111  bool withMetadata,
1112  bool onDevice,
1113  parallelDeviceEvents & events ) const
1114  {
1115  localIndex packedSize = 0;
1116 
1117  if( withMetadata )
1118  { packedSize += bufferOps::Pack< DO_PACKING >( buffer, getName() ); }
1119  if( onDevice )
1120  {
1121  if( withMetadata )
1122  {
1123  packedSize += wrapperHelpers::PackDevice< DO_PACKING >( buffer, reference(), events );
1124  }
1125  else
1126  {
1127  packedSize += wrapperHelpers::PackDataDevice< DO_PACKING >( buffer, reference(), events );
1128  }
1129  }
1130  else
1131  {
1132  packedSize += bufferOps::Pack< DO_PACKING >( buffer, *m_data );
1133  }
1134 
1135  return packedSize;
1136  }
1137 
1151  template< bool DO_PACKING >
1152  localIndex packByIndexImpl( buffer_unit_type * & buffer,
1153  arrayView1d< localIndex const > const & packList,
1154  bool withMetadata,
1155  bool onDevice,
1156  parallelDeviceEvents & events ) const
1157  {
1158  localIndex packedSize = 0;
1159 
1160  if( withMetadata )
1161  { packedSize += bufferOps::Pack< DO_PACKING >( buffer, getName() ); }
1162  if( onDevice )
1163  {
1164  if( withMetadata )
1165  {
1166  packedSize += wrapperHelpers::PackByIndexDevice< DO_PACKING >( buffer, reference(), packList, events );
1167  }
1168  else
1169  {
1170  packedSize += wrapperHelpers::PackDataByIndexDevice< DO_PACKING >( buffer, reference(), packList, events );
1171  }
1172  }
1173  else
1174  {
1175  packedSize += wrapperHelpers::PackByIndex< DO_PACKING >( buffer, *m_data, packList );
1176  }
1177 
1178  return packedSize;
1179  }
1180 
1184  localIndex packPrivate( buffer_unit_type * & buffer,
1185  bool withMetadata,
1186  bool onDevice,
1187  parallelDeviceEvents & events ) const override final
1188  {
1189  return this->packImpl< true >( buffer, withMetadata, onDevice, events );
1190  }
1191 
1195  localIndex packByIndexPrivate( buffer_unit_type * & buffer,
1196  arrayView1d< localIndex const > const & packList,
1197  bool withMetadata,
1198  bool onDevice,
1199  parallelDeviceEvents & events ) const override final
1200  {
1201  return this->packByIndexImpl< true >( buffer, packList, withMetadata, onDevice, events );
1202  }
1203 
1207  localIndex packSizePrivate( bool withMetadata,
1208  bool onDevice,
1209  parallelDeviceEvents & events ) const override final
1210  {
1211  buffer_unit_type * dummy;
1212  return this->packImpl< false >( dummy, withMetadata, onDevice, events );
1213  }
1214 
1218  localIndex packByIndexSizePrivate( arrayView1d< localIndex const > const & packList,
1219  bool withMetadata,
1220  bool onDevice,
1221  parallelDeviceEvents & events ) const override final
1222  {
1223  buffer_unit_type * dummy;
1224  return this->packByIndexImpl< false >( dummy, packList, withMetadata, onDevice, events );
1225  }
1226 
1227  template< typename V >
1228  void validateLimitValue( V const & value ) const
1229  {
1230  bool const belowMin = m_limits.min.has_value() ? isValueBelowMin( value, *m_limits.min ) : false;
1231  bool const aboveMax = m_limits.max.has_value() ? isValueAboveMax( value, *m_limits.max ) : false;
1232  if( !belowMin && !aboveMax )
1233  {
1234  return;
1235  }
1236 
1237  string const msg = GEOS_FMT( "Value {} is outside the allowed range {}.",
1238  value, m_limits.getRangeStr() );
1239 
1240  switch( m_limitsMode )
1241  {
1242  case LimitsMode::Warning:
1243  GEOS_WARNING( msg, getDataContext() );
1244  break;
1245 
1246  case LimitsMode::Error:
1247  GEOS_THROW( msg, InputError, getDataContext() );
1248  break;
1249 
1250  default:
1251  GEOS_LOG_RANK_0( "Unimplemented LimitsMode" );
1252  break;
1253  }
1254  }
1255 
1258  bool m_ownsData;
1259 
1260  bool m_isClone;
1261 
1263  T * m_data;
1264 
1266  DefaultValue< T > m_default;
1267 
1269  wrapperHelpers::ArrayDimLabels< T > m_dimLabels;
1270 
1272  Limits< T > m_limits;
1273 };
1274 
1275 }
1276 
1277 } // end of namespace geos
1278 
1279 // Do not remove the following commented code since it's used for debugging with TotalView.
1280 //template< typename T >
1281 //int TV_ttf_display_type( geos::dataRepository::Wrapper<T> const * wrapper)
1282 //{
1283 // std::cout<<"Executing "<<wrapper->totalviewTypeName()<<"::TV_ttf_display_type()"<<std::endl;
1284 // return TV_ttf_format_raw;
1285 //}
1286 //
1287 //template int TV_ttf_display_type( geos::dataRepository::Wrapper<int> const * wrapper );
1288 //
1289 //template< typename T >
1290 //void geos::dataRepository::Wrapper<T>::tvTemplateInstantiation()
1291 //{
1292 // TV_ttf_display_type<T>(this);
1293 //}
1294 
1295 #endif /* GEOS_DATAREPOSITORY_WRAPPER_HPP_ */
#define GEOS_DECLTYPE_AUTO_RETURN
Doxygen can't parse a decltype( auto ) return type, using this gets around that.
#define GEOS_UNUSED_PARAM(X)
Mark an unused argument and silence compiler warnings.
Definition: GeosxMacros.hpp:97
#define GEOS_THROW(MSG,...)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:315
#define GEOS_ERROR_IF(COND,...)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:216
#define GEOS_LOG_RANK_0(msg)
Log a message on screen on rank 0.
Definition: Logger.hpp:99
#define GEOS_WARNING(...)
Report a warning.
Definition: Logger.hpp:401
#define GEOS_THROW_IF(COND, MSG,...)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:305
#define GEOS_ASSERT_LE_MSG(lhs, rhs,...)
Assert that one value compares greater than or equal to the other in debug builds.
Definition: Logger.hpp:960
A minimal class to specify information about time history information being collected and output.
Lightweight non-owning wrapper over a contiguous range of elements.
Definition: Span.hpp:42
Base class for all wrappers containing common operations.
Definition: WrapperBase.hpp:57
string const & getName() const
Get name of the wrapper.
WrapperBase & setInputFlag(InputFlags const input)
Set the InputFlag of the wrapper.
WrapperBase & setDescription(string const &description)
Set the description string of the wrapper.
WrapperBase & setSizedFromParent(int val)
Set whether this wrapper is resized when its parent is resized.
virtual void copyWrapperAttributes(WrapperBase const &source)
Copy attributes from another wrapper.
WrapperBase & setRegisteringObjects(string const &objectName)
Add a new name to the list of groups that register this wrapper.
WrapperBase & setRestartFlags(RestartFlags flags)
Set the RestartFlags of the wrapper.
WrapperBase & appendDescription(string const &description)
Add up more text to the existing description string of the wrapper.
virtual std::type_info const & getTypeId() const =0
Get the typeid of T.
WrapperBase & setRTTypeName(string_view rtTypeName)
override the rtType to use when parsing an input value to the wrapped object. It can be useful to cha...
WrapperBase & setPlotLevel(PlotLevel const flag)
Set the PlotLevel of the wrapper.
Wrapper< T > & setRTTypeName(string_view rtTypeName)
override the rtType to use when parsing an input value to the wrapped object. It can be useful to cha...
Definition: Wrapper.hpp:1063
Wrapper< T > & setRestartFlags(RestartFlags flags)
Set the RestartFlags of the wrapper.
Definition: Wrapper.hpp:1009
virtual string getLimitsString() const override
Return a string representing the allowed value range.
Definition: Wrapper.hpp:799
virtual const std::type_info & getTypeId() const noexcept override
Get the typeid of T.
Definition: Wrapper.hpp:212
Wrapper & operator=(Wrapper &&source)
Move Assignment Operator.
Definition: Wrapper.hpp:170
virtual void copyWrapperAttributes(WrapperBase const &source) override
Copy attributes from another wrapper.
Definition: Wrapper.hpp:201
Wrapper< T > & setInputFlag(InputFlags const input)
Set the InputFlag of the wrapper.
Definition: Wrapper.hpp:1027
T TYPE
Alias for the wrapped type T.
Definition: Wrapper.hpp:65
void registerToWrite() const override
Register the wrapper's data for writing with Conduit.
Definition: Wrapper.hpp:945
std::enable_if_t< !traits::is_array< U > &&DefaultValue< U >::has_default_value, Wrapper< T > & > setApplyDefaultValue(typename DefaultValue< U >::value_type const &defaultVal)
Set and apply for default value.
Definition: Wrapper.hpp:692
std::enable_if_t< is_limitable_v< U >, std::optional< Bound< limit_value_type_t< T > > > const & > getMaxBound() const
Accessor for the maximum bound of this attribute's value.
Definition: Wrapper.hpp:791
virtual void resize(localIndex const newSize) override
Calls T::resize(newsize) if it exists.
Definition: Wrapper.hpp:413
std::enable_if_t< is_limitable_v< U >, Wrapper< T > & > setLimits(std::optional< LimitArg< limit_value_type_t< T > > > min, std::optional< LimitArg< limit_value_type_t< T > > > max, LimitsMode mode=LimitsMode::Error)
Set both bounds for this attribute's value.
Definition: Wrapper.hpp:743
virtual void reserve(localIndex const newCapacity) override
Calls T::reserve( newCapacity ) if it exists, otherwise a no-op.
Definition: Wrapper.hpp:399
virtual bool isPackable(bool onDevice) const override
Check whether wrapped type is can be packed into a buffer on host or device.
Definition: Wrapper.hpp:283
Wrapper< T > & setRegisteringObjects(string const &objectName)
Add a new name to the list of groups that register this wrapper.
Definition: Wrapper.hpp:1054
static Wrapper< T > const & cast(WrapperBase const &wrapper)
Downcast base to a const typed wrapper.
Definition: Wrapper.hpp:236
GEOS_DECLTYPE_AUTO_RETURN referenceAsView() const
Provide access to wrapped object converted to a view, if possible.
Definition: Wrapper.hpp:624
void setName()
DO_NOT_DOCUMENT.
Definition: Wrapper.hpp:912
T & referenceAsView()
Provide access to wrapped object converted to a view, if possible.
Definition: Wrapper.hpp:617
virtual ~Wrapper() noexcept override
Default destructor.
Definition: Wrapper.hpp:144
Wrapper(string const &name, Group &parent, std::unique_ptr< T > object)
Constructor that takes ownership of an existing object.
Definition: Wrapper.hpp:99
std::enable_if_t< traits::is_array< U > &&DefaultValue< U >::has_default_value, Wrapper< T > & > setApplyDefaultValue(typename DefaultValue< U >::value_type const &defaultVal)
Set and apply for default value.
Definition: Wrapper.hpp:706
Wrapper< T > & setPlotLevel(PlotLevel const flag)
Set the PlotLevel of the wrapper.
Definition: Wrapper.hpp:1018
virtual void copy(localIndex const sourceIndex, localIndex const destIndex) override
Calls T::copy(sourceIndex, destIndex)
Definition: Wrapper.hpp:458
virtual localIndex capacity() const override
Definition: Wrapper.hpp:406
GEOS_DECLTYPE_AUTO_RETURN referenceAsView()
Provide access to wrapped object converted to a view, if possible.
Definition: Wrapper.hpp:610
GEOS_DECLTYPE_AUTO_RETURN reference() const
const Accessor for m_data
Definition: Wrapper.hpp:598
virtual size_t bytesAllocated() const override final
Definition: Wrapper.hpp:373
virtual localIndex unpack(buffer_unit_type const *&buffer, bool withMetadata, bool onDevice, parallelDeviceEvents &events) override final
Unpack the entire wrapped object from a buffer.
Definition: Wrapper.hpp:299
virtual HistoryMetadata getHistoryMetadata(localIndex const packCount=-1) const override final
Get a description of the wrapped data for time history collection/output.
Definition: Wrapper.hpp:270
Wrapper(string const &name, Group &parent, T *object)
Constructor that does not take ownership of an existing object.
Definition: Wrapper.hpp:122
Wrapper< T > & setDescription(string const &description)
Set the description string of the wrapper.
Definition: Wrapper.hpp:1036
virtual localIndex numArrayComp() const override
Return the number of components in a multidimensional array.
Definition: Wrapper.hpp:250
Wrapper(string const &name, Group &parent)
Constructor that creates a new instance of wrapped type.
Definition: Wrapper.hpp:77
virtual bool processInputFile(xmlWrapper::xmlNode const &targetNode, xmlWrapper::xmlNodePos const &nodePos) override
Initialize the wrapper from the input xml node.
Definition: Wrapper.hpp:854
virtual void resize(int ndims, localIndex const *const dims) override
Calls T::resize( num_dims, dims )
Definition: Wrapper.hpp:392
Wrapper< T > & appendDescription(string const &description)
Add up more text to the existing description string of the wrapper.
Definition: Wrapper.hpp:1045
void finishWriting() const override
Write the wrapped data into Conduit.
Definition: Wrapper.hpp:962
virtual localIndex size() const override
Calls T::size()
Definition: Wrapper.hpp:388
virtual localIndex unpackByIndex(buffer_unit_type const *&buffer, arrayView1d< localIndex const > const &unpackIndices, bool withMetadata, bool onDevice, parallelDeviceEvents &events, MPI_Op op) override final
For indexable types, unpack selected indices of wrapped object from a buffer.
Definition: Wrapper.hpp:329
T const & referenceAsView() const
Provide access to wrapped object converted to a view, if possible.
Definition: Wrapper.hpp:631
virtual string getDefaultValueString() const override
Return a string representing the default value.
Definition: Wrapper.hpp:716
bool loadFromConduit() override
Read the wrapped data from Conduit.
Definition: Wrapper.hpp:967
DefaultValue< T > const & getDefaultValueStruct() const
Accessor for m_default.
Definition: Wrapper.hpp:655
virtual int numArrayDims() const override
Return the number of dimensions of the array.
Definition: Wrapper.hpp:245
void const * voidPointer() const override
Definition: Wrapper.hpp:366
std::enable_if_t< DefaultValue< U >::has_default_value, Wrapper< T > & > setDefaultValue(typename DefaultValue< U >::value_type const &defaultVal)
Setter for default value.
Definition: Wrapper.hpp:679
Wrapper< T > & setSizedFromParent(int val)
Set whether this wrapper is resized when its parent is resized.
Definition: Wrapper.hpp:1000
virtual bool hasDefaultValue() const final override
Return true iff this wrapper has a valid default value.
Definition: Wrapper.hpp:644
std::enable_if_t< DefaultValue< U >::has_default_value, typename DefaultValue< U >::value_type const & > getDefaultValue() const
Accessor for default value.
Definition: Wrapper.hpp:667
Wrapper & operator=(Wrapper const &source)
Copy Assignment Operator.
Definition: Wrapper.hpp:159
virtual void copyWrapper(WrapperBase const &source) override
Copies the contents of a Wrapper into *this.
Definition: Wrapper.hpp:193
void erase(std::set< localIndex > const &indicesToErase) override
Calls T::erase(indicesToErase)
Definition: Wrapper.hpp:564
static Wrapper & cast(WrapperBase &wrapper)
Downcast base to a typed wrapper.
Definition: Wrapper.hpp:223
virtual Regex const & getTypeRegex() const override
Definition: Wrapper.hpp:576
virtual void copyData(WrapperBase const &source) override
Copy the the data contained in another wrapper into this wrapper.
Definition: Wrapper.hpp:465
T & reference()
Accessor for m_data.
Definition: Wrapper.hpp:590
std::enable_if_t< is_limitable_v< U >, std::optional< Bound< limit_value_type_t< T > > > const & > getMinBound() const
Accessor for the minimum bound of this attribute's value.
Definition: Wrapper.hpp:779
virtual void move(LvArray::MemorySpace const space, bool const touch) const override
Calls T::move(space, touch)
Definition: Wrapper.hpp:572
virtual localIndex elementByteSize() const override
Definition: Wrapper.hpp:370
virtual Span< string const > getDimLabels(integer const dim) const override
Get dimension labels of an array.
Definition: Wrapper.hpp:261
@ OPTIONAL
Optional in input.
@ REQUIRED
Required in input.
internal::Helper< T > DefaultValue
A templated alias to hold default values.
@ WRITE_AND_READ
Write and read from restart.
@ NO_WRITE
Do not write into restart.
pugi::xml_node xmlNode
Definition: xmlWrapper.hpp:59
std::enable_if_t< !internal::canParseVariable< T >, bool > readAttributeAsType(T &, string const &name, Regex const &, xmlNode const &, U const &)
Extract attribute in an xml tree, and translate its value into a typed variable. This SFINAE implemen...
Definition: xmlWrapper.hpp:464
void processInputException(std::exception const &ex, string const &targetAttributeName, xmlWrapper::xmlNode const &targetNode, xmlWrapper::xmlNodePos const &nodePos)
Helper method to process an exception that has been thrown during xml parsing.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:179
LvArray::Array< T, NDIM, PERMUTATION, localIndex, LvArray::ChaiBuffer > Array
Multidimensional array type. See LvArray:Array for details.
Definition: DataTypes.hpp:141
std::string string
String type.
Definition: DataTypes.hpp:90
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:84
void erase(OrderedVariableToManyElementRelation &relation, localIndex const firstIndex, localIndex const er, localIndex const esr, localIndex const ei)
Remove an element relation from an object in the relation.
signed char buffer_unit_type
Type stored in communication buffers.
Definition: DataTypes.hpp:108
int integer
Signed integer type.
Definition: DataTypes.hpp:81
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:175
std::enable_if< can_history_io< T >, HistoryMetadata >::type getHistoryMetadata(string const &name, ArrayView< T const, 1, 0 > const &arr, localIndex const numComps, localIndex sizeOverride=-1)
Produce a HistoryMetadata object for a supported one-dimensional array type.
std::string_view string_view
String type.
Definition: DataTypes.hpp:93
internal::StdVectorWrapper< T, Allocator, USE_STD_CONTAINER_BOUNDS_CHECKING > stdVector
Exception class used to report errors in user input.